diff --git a/pkg/metric/BUILD b/pkg/metric/BUILD index fc99e4798..cb4ef6ae0 100644 --- a/pkg/metric/BUILD +++ b/pkg/metric/BUILD @@ -8,12 +8,12 @@ package( go_library( name = "metric", srcs = [ - "condmetric_profiling.go", - "condmetric_profiling_fake.go", - "fake_metric.go", + "condmetric.go", "metric.go", "metric_unsafe.go", "profiling_metric.go", + "sentry_profiling.go", + "sentry_profiling_fake.go", ], visibility = ["//:sandbox"], deps = [ diff --git a/pkg/metric/condmetric.go b/pkg/metric/condmetric.go new file mode 100644 index 000000000..f929255f5 --- /dev/null +++ b/pkg/metric/condmetric.go @@ -0,0 +1,155 @@ +// Copyright 2022 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 ( + "fmt" + + pb "gvisor.dev/gvisor/pkg/metric/metric_go_proto" +) + +// FakeUint64Metric is a type that implements all the methods of a Uint64Metric +// as a no-op. +type FakeUint64Metric struct{} + +// FakeDistributionMetric is a type that implements all the methods of a +// DistributionMetric as a no-op. +type FakeDistributionMetric struct{} + +// FakeTimerMetric is a type that implements all the methods of a TimerMetric +// as a no-op. +type FakeTimerMetric struct{} + +// FakeTimedOperation is a type that implements all the methods of a +// TimedOperation as a no-op. +type FakeTimedOperation struct{} + +// Value from a FakeUint64Metric always returns a meaningless value. +// +//go:nosplit +func (m *FakeUint64Metric) Value(fieldValues ...*FieldValue) uint64 { + return 0 +} + +// Increment on a FakeUint64Metric does nothing. +// +//go:nosplit +func (m *FakeUint64Metric) Increment(fieldValues ...*FieldValue) {} + +// IncrementBy on a FakeUint64Metric does nothing. +// +//go:nosplit +func (m *FakeUint64Metric) IncrementBy(v uint64, fieldValues ...*FieldValue) {} + +// AddSample on a FakeUint64Metric does nothing. +// +//go:nosplit +func (d *FakeDistributionMetric) AddSample(sample int64, fields ...*FieldValue) {} + +// Start on a FakeUint64Metric returns a FakeTimedOperation struct, which does +// nothing and does not keep the time. +// +//go:nosplit +func (t *FakeTimerMetric) Start(fields ...*FieldValue) FakeTimedOperation { + return FakeTimedOperation{} +} + +// Finish on a FakeTimedOperation does nothing. +// +//go:nosplit +func (o FakeTimedOperation) Finish(extraFields ...*FieldValue) {} + +// FakeMetricBuilder is a type used to produce conditionally compiled metrics. +// Methods of this struct produce fake, inactive metrics. +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) { + return &FakeUint64Metric{}, nil +} + +// MustCreateNewUint64Metric creates a fake Uint64 metric. +func (b *FakeMetricBuilder) MustCreateNewUint64Metric(name string, sync bool, description string, fields ...Field) *FakeUint64Metric { + return &FakeUint64Metric{} +} + +// NewDistributionMetric creates a fake distribution metric. +func (b *FakeMetricBuilder) NewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) (*FakeDistributionMetric, error) { + return &FakeDistributionMetric{}, nil +} + +// MustCreateNewDistributionMetric creates a fake distribution metric. +func (b *FakeMetricBuilder) MustCreateNewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) *FakeDistributionMetric { + return &FakeDistributionMetric{} +} + +// NewTimerMetric creates a fake timer metric. +func (b *FakeMetricBuilder) NewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) (*FakeTimerMetric, error) { + return &FakeTimerMetric{}, nil +} + +// MustCreateNewTimerMetric creates a fake timer metric. +func (b *FakeMetricBuilder) MustCreateNewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) *FakeTimerMetric { + return &FakeTimerMetric{} +} + +// RealMetricBuilder is a type used to produce conditionally compiled metrics. +// Methods of this struct produce real active metrics. +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...) + if err != nil { + return m, err + } + definedProfilingMetrics = append(definedProfilingMetrics, m.name) + return m, err +} + +// 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...) + if err != nil { + panic(fmt.Sprintf("Unable to create metric %q: %s", name, err)) + } + return m +} + +// NewDistributionMetric calls the generic metric.NewDistributionMetric to +// produce a real distribution metric. +func (b *RealMetricBuilder) NewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) (*DistributionMetric, error) { + return NewDistributionMetric(name, sync, bucketer, unit, description, fields...) +} + +// MustCreateNewDistributionMetric creates a real distribution metric or panics +// if unable to do so. +func (b *RealMetricBuilder) MustCreateNewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) *DistributionMetric { + return MustCreateNewDistributionMetric(name, sync, bucketer, unit, description, fields...) +} + +// NewTimerMetric calls the generic metric.NewTimerMetric to produce a real timer +// metric. +func (b *RealMetricBuilder) NewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) (*TimerMetric, error) { + return NewTimerMetric(name, nanoBucketer, description, fields...) +} + +// MustCreateNewTimerMetric creates a real timer metric or panics if unable to +// do so. +func (b *RealMetricBuilder) MustCreateNewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) *TimerMetric { + return MustCreateNewTimerMetric(name, nanoBucketer, description, fields...) +} diff --git a/pkg/metric/condmetric_profiling.go b/pkg/metric/condmetric_profiling.go deleted file mode 100644 index 99a7e35c2..000000000 --- a/pkg/metric/condmetric_profiling.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2022 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. - -//go:build condmetric_profiling -// +build condmetric_profiling - -package metric - -import ( - "fmt" - - pb "gvisor.dev/gvisor/pkg/metric/metric_go_proto" -) - -// This file defines conditional metrics that are meant to be used when profiling -// runsc during benchmark tests. - -// ProfilingUint64Metric is a metric type that is registered and used only when -// the "condmetric_profiling" go tag is specified for go build. -// -// Otherwise it is exactly like a Uint64Metric. -type ProfilingUint64Metric = Uint64Metric - -// ProfilingDistributionMetric is a metric type that is registered and used only -// when the "condmetric_profiling" go tag is specified for go build. -// -// Otherwise it is exactly like a DistributionMetric. -type ProfilingDistributionMetric = DistributionMetric - -// ProfilingTimerMetric is a metric type that is registered and used only when -// the "condmetric_profiling" go tag is specified for go build. -// -// Otherwise it is exactly like a TimerMetric. -type ProfilingTimerMetric = TimerMetric - -// NewProfilingUint64Metric is equivalent to NewUint64Metric except it creates a -// ProfilingUint64Metric -var NewProfilingUint64Metric = newProfilingUint64Metric - -// MustCreateNewProfilingUint64Metric is equivalent to MustCreateNewUint64Metric -// except it creates a ProfilingUint64Metric. -var MustCreateNewProfilingUint64Metric = mustCreateNewProfilingUint64Metric - -// NewProfilingDistributionMetric is equivalent to NewDistributionMetric except -// it creates a ProfilingDistributionMetric. -var NewProfilingDistributionMetric = NewDistributionMetric - -// MustCreateNewProfilingDistributionMetric is equivalent to -// MustCreateNewDistributionMetric except it creates a -// ProfilingDistributionMetric. -var MustCreateNewProfilingDistributionMetric = MustCreateNewDistributionMetric - -// NewProfilingTimerMetric is equivalent to NewTimerMetric except it creates a -// ProfilingTimerMetric. -var NewProfilingTimerMetric = NewTimerMetric - -// MustCreateNewProfilingTimerMetric is equivalent to MustCreateNewTimerMetric -// except it creates a ProfilingTimerMetric. -var MustCreateNewProfilingTimerMetric = MustCreateNewTimerMetric - -func newProfilingUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*Uint64Metric, error) { - m, err := NewUint64Metric(name, sync, units, description, fields...) - if err != nil { - return m, err - } - definedProfilingMetrics = append(definedProfilingMetrics, m.name) - return m, err -} - -func mustCreateNewProfilingUint64Metric(name string, sync bool, description string, fields ...Field) *Uint64Metric { - m, err := newProfilingUint64Metric(name, sync, pb.MetricMetadata_UNITS_NONE, description, fields...) - if err != nil { - panic(fmt.Sprintf("Unable to create metric %q: %s", name, err)) - } - return m -} diff --git a/pkg/metric/condmetric_profiling_disabled_test.go b/pkg/metric/condmetric_profiling_disabled_test.go index ac02caacb..45e86ede4 100644 --- a/pkg/metric/condmetric_profiling_disabled_test.go +++ b/pkg/metric/condmetric_profiling_disabled_test.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !condmetric_profiling -// +build !condmetric_profiling +//go:build !sentry_profiling +// +build !sentry_profiling package metric @@ -26,20 +26,20 @@ import ( func TestProfilingMetricsDisabled(t *testing.T) { defer resetTest() - _, err := NewProfilingUint64Metric("counterM", false, pb.MetricMetadata_UNITS_NONE, "One uint64 metric") + _, err := SentryProfiling.NewUint64Metric("/counterM", false, pb.MetricMetadata_UNITS_NONE, "One uint64 metric") if err != nil { - t.Fatalf("NewProfilingUint64Metric got err %v want nil", err) + t.Fatalf("NewUint64Metric got err %v want nil", err) } bucketer := NewExponentialBucketer(3, 2, 0, 1) - _, err = NewProfilingDistributionMetric("distribM", false, bucketer, pb.MetricMetadata_UNITS_NANOSECONDS, "One distribution metric") + _, err = SentryProfiling.NewDistributionMetric("/distribM", false, bucketer, pb.MetricMetadata_UNITS_NANOSECONDS, "One distribution metric") if err != nil { - t.Fatalf("NewProfilingDistributionMetric got err %v want nil", err) + t.Fatalf("NewDistributionMetric got err %v want nil", err) } - _, err = NewProfilingTimerMetric("timerM", bucketer, "One timer metric") + _, err = SentryProfiling.NewTimerMetric("/timerM", bucketer, "One timer metric") if err != nil { - t.Fatalf("NewProfilingTimerMetric got err %v want nil", err) + t.Fatalf("NewTimerMetric got err %v want nil", err) } if err := Initialize(); err != nil { diff --git a/pkg/metric/condmetric_profiling_enabled_test.go b/pkg/metric/condmetric_profiling_enabled_test.go index db64fe3b0..b45288b69 100644 --- a/pkg/metric/condmetric_profiling_enabled_test.go +++ b/pkg/metric/condmetric_profiling_enabled_test.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build condmetric_profiling -// +build condmetric_profiling +//go:build sentry_profiling +// +build sentry_profiling package metric @@ -26,20 +26,20 @@ import ( func TestProfilingMetricsEnabled(t *testing.T) { defer resetTest() - _, err := NewProfilingUint64Metric("counterM", false, pb.MetricMetadata_UNITS_NONE, "One uint64 metric") + _, err := SentryProfiling.NewUint64Metric("/counterM", false, pb.MetricMetadata_UNITS_NONE, "One uint64 metric") if err != nil { - t.Fatalf("NewProfilingUint64Metric got err %v want nil", err) + t.Fatalf("NewUint64Metric got err %v want nil", err) } bucketer := NewExponentialBucketer(3, 2, 0, 1) - _, err = NewProfilingDistributionMetric("distribM", false, bucketer, pb.MetricMetadata_UNITS_NANOSECONDS, "One distribution metric") + _, err = SentryProfiling.NewDistributionMetric("/distribM", false, bucketer, pb.MetricMetadata_UNITS_NANOSECONDS, "One distribution metric") if err != nil { - t.Fatalf("NewProfilingDistributionMetric got err %v want nil", err) + t.Fatalf("NewDistributionMetric got err %v want nil", err) } - _, err = NewProfilingTimerMetric("timerM", bucketer, "One timer metric") + _, err = SentryProfiling.NewTimerMetric("/timerM", bucketer, "One timer metric") if err != nil { - t.Fatalf("NewProfilingTimerMetric got err %v want nil", err) + t.Fatalf("NewTimerMetric got err %v want nil", err) } if err := Initialize(); err != nil { diff --git a/pkg/metric/condmetric_profiling_fake.go b/pkg/metric/condmetric_profiling_fake.go deleted file mode 100644 index 30433a13e..000000000 --- a/pkg/metric/condmetric_profiling_fake.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2022 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. - -//go:build !condmetric_profiling -// +build !condmetric_profiling - -package metric - -// ProfilingUint64Metric is a metric type that is registered and used only when -// the "condmetric_profiling" go tag is specified when building runsc. -// -// Otherwise it is exactly like a Uint64Metric. -type ProfilingUint64Metric = FakeUint64Metric - -// ProfilingDistributionMetric is a metric type that is registered and used only -// when the "condmetric_profiling" go tag is specified when building runsc. -// -// Otherwise it is exactly like a DistributionMetric. -type ProfilingDistributionMetric = FakeDistributionMetric - -// ProfilingTimerMetric is a metric type that is registered and used only when -// the "condmetric_profiling" go tag is specified when building runsc. -// -// Otherwise it is exactly like a TimerMetric. -type ProfilingTimerMetric = FakeTimerMetric - -// NewProfilingUint64Metric is equivalent to NewUint64Metric except it creates a -// ProfilingUint64Metric -var NewProfilingUint64Metric = NewFakeUint64Metric - -// MustCreateNewProfilingUint64Metric is equivalent to MustCreateNewUint64Metric -// except it creates a ProfilingUint64Metric. -var MustCreateNewProfilingUint64Metric = MustCreateNewFakeUint64Metric - -// NewProfilingDistributionMetric is equivalent to NewDistributionMetric except -// it creates a ProfilingDistributionMetric. -var NewProfilingDistributionMetric = NewFakeDistributionMetric - -// MustCreateNewProfilingDistributionMetric is equivalent to -// MustCreateNewDistributionMetric except it creates a -// ProfilingDistributionMetric. -var MustCreateNewProfilingDistributionMetric = MustCreateNewFakeDistributionMetric - -// NewProfilingTimerMetric is equivalent to NewTimerMetric except it creates a -// ProfilingTimerMetric. -var NewProfilingTimerMetric = NewFakeTimerMetric - -// MustCreateNewProfilingTimerMetric is equivalent to MustCreateNewTimerMetric -// except it creates a ProfilingTimerMetric. -var MustCreateNewProfilingTimerMetric = MustCreateNewFakeTimerMetric diff --git a/pkg/metric/fake_metric.go b/pkg/metric/fake_metric.go deleted file mode 100644 index 323f35af2..000000000 --- a/pkg/metric/fake_metric.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2022 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 pb "gvisor.dev/gvisor/pkg/metric/metric_go_proto" - -// FakeUint64Metric is a type that implements all the methods of a Uint64Metric -// as a no-op. -type FakeUint64Metric struct{} - -// FakeDistributionMetric is a type that implements all the methods of a -// DistributionMetric as a no-op. -type FakeDistributionMetric struct{} - -// FakeTimerMetric is a type that implements all the methods of a TimerMetric -// as a no-op. -type FakeTimerMetric struct{} - -// FakeTimedOperation is a type that implements all the methods of a -// TimedOperation as a no-op. -type FakeTimedOperation struct{} - -// Value from a FakeUint64Metric always returns a meaningless value. -// -//go:nosplit -func (m *FakeUint64Metric) Value(fieldValues ...*FieldValue) uint64 { - return 0 -} - -// Increment on a FakeUint64Metric does nothing. -// -//go:nosplit -func (m *FakeUint64Metric) Increment(fieldValues ...*FieldValue) {} - -// IncrementBy on a FakeUint64Metric does nothing. -// -//go:nosplit -func (m *FakeUint64Metric) IncrementBy(v uint64, fieldValues ...*FieldValue) {} - -// AddSample on a FakeUint64Metric does nothing. -// -//go:nosplit -func (d *FakeDistributionMetric) AddSample(sample int64, fields ...*FieldValue) {} - -// Start on a FakeUint64Metric returns a FakeTimedOperation struct, which does -// nothing and does not keep the time. -// -//go:nosplit -func (t *FakeTimerMetric) Start(fields ...*FieldValue) FakeTimedOperation { - return FakeTimedOperation{} -} - -// Finish on a FakeTimedOperation does nothing. -// -//go:nosplit -func (o FakeTimedOperation) Finish(extraFields ...*FieldValue) {} - -// NewFakeUint64Metric is equivalent to NewUint64Metric except it creates a -// FakeUint64Metric -func NewFakeUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*FakeUint64Metric, error) { - return &FakeUint64Metric{}, nil -} - -// MustCreateNewFakeUint64Metric is equivalent to MustCreateNewUint64Metric -// except it creates a FakeUint64Metric. -func MustCreateNewFakeUint64Metric(name string, sync bool, description string, fields ...Field) *FakeUint64Metric { - return &FakeUint64Metric{} -} - -// NewFakeDistributionMetric is equivalent to NewDistributionMetric except -// it creates a FakeDistributionMetric. -func NewFakeDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) (*FakeDistributionMetric, error) { - return &FakeDistributionMetric{}, nil -} - -// MustCreateNewFakeDistributionMetric is equivalent to -// MustCreateNewDistributionMetric except it creates a FakeDistributionMetric. -func MustCreateNewFakeDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) *FakeDistributionMetric { - return &FakeDistributionMetric{} -} - -// NewFakeTimerMetric is equivalent to NewTimerMetric except it creates a -// FakeTimerMetric. -func NewFakeTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) (*FakeTimerMetric, error) { - return &FakeTimerMetric{}, nil -} - -// MustCreateNewFakeTimerMetric is equivalent to MustCreateNewTimerMetric -// except it creates a FakeTimerMetric. -func MustCreateNewFakeTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) *FakeTimerMetric { - return &FakeTimerMetric{} -} diff --git a/pkg/metric/sentry_profiling.go b/pkg/metric/sentry_profiling.go new file mode 100644 index 000000000..41c1facf6 --- /dev/null +++ b/pkg/metric/sentry_profiling.go @@ -0,0 +1,23 @@ +// Copyright 2023 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. + +//go:build sentry_profiling +// +build sentry_profiling + +package metric + +// SentryProfiling is a builder that produces conditionally compiled metrics. +// Metrics made from this are compiled and active at runtime when the +// "sentry_profiling" go-tag is specified at compilation. +var SentryProfiling = RealMetricBuilder{} diff --git a/pkg/metric/sentry_profiling_fake.go b/pkg/metric/sentry_profiling_fake.go new file mode 100644 index 000000000..29a287c46 --- /dev/null +++ b/pkg/metric/sentry_profiling_fake.go @@ -0,0 +1,23 @@ +// Copyright 2023 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. + +//go:build !sentry_profiling +// +build !sentry_profiling + +package metric + +// SentryProfiling is a builder that produces conditionally compiled metrics. +// Metrics made from this are compiled and active at runtime when the +// "sentry_profiling" go-tag is specified at compilation. +var SentryProfiling = FakeMetricBuilder{} diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index b26e2496e..06517f005 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -610,12 +610,12 @@ type Task struct { var ( // syscallCounter is a metric that tracks how many syscalls the sentry has // executed. - syscallCounter = metric.MustCreateNewProfilingUint64Metric( + syscallCounter = metric.SentryProfiling.MustCreateNewUint64Metric( "/task/syscalls", false, "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.MustCreateNewProfilingUint64Metric( + faultCounter = metric.SentryProfiling.MustCreateNewUint64Metric( "/task/faults", false, "The number of faults the sentry has handled.") ) diff --git a/pkg/sentry/platform/kvm/BUILD b/pkg/sentry/platform/kvm/BUILD index c0b3e8b87..d836ec796 100644 --- a/pkg/sentry/platform/kvm/BUILD +++ b/pkg/sentry/platform/kvm/BUILD @@ -46,6 +46,8 @@ go_library( "kvm_const.go", "kvm_const_amd64.go", "kvm_const_arm64.go", + "kvm_profiling.go", + "kvm_profiling_fake.go", "machine.go", "machine_amd64.go", "machine_amd64_unsafe.go", diff --git a/pkg/sentry/platform/kvm/kvm_profiling.go b/pkg/sentry/platform/kvm/kvm_profiling.go new file mode 100644 index 000000000..362ff1673 --- /dev/null +++ b/pkg/sentry/platform/kvm/kvm_profiling.go @@ -0,0 +1,27 @@ +// Copyright 2023 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. + +//go:build kvm_profiling +// +build kvm_profiling + +package kvm + +import ( + "gvisor.dev/gvisor/pkg/metric" +) + +// KVMProfiling is a builder that produces conditionally compiled metrics. +// Metrics made from this are compiled and active at runtime when the +// "kvm_profiling" go-tag is specified at compilation. +var KVMProfiling = metric.RealMetricBuilder{} diff --git a/pkg/sentry/platform/kvm/kvm_profiling_fake.go b/pkg/sentry/platform/kvm/kvm_profiling_fake.go new file mode 100644 index 000000000..0bf5132a4 --- /dev/null +++ b/pkg/sentry/platform/kvm/kvm_profiling_fake.go @@ -0,0 +1,27 @@ +// Copyright 2023 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. + +//go:build !kvm_profiling +// +build !kvm_profiling + +package kvm + +import ( + "gvisor.dev/gvisor/pkg/metric" +) + +// KVMProfiling is a builder that produces conditionally compiled metrics. +// Metrics made from this are compiled and active at runtime when the +// "kvm_profiling" go-tag is specified at compilation. +var KVMProfiling = metric.FakeMetricBuilder{} diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index d1163b23b..9c103b11e 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -114,32 +114,32 @@ var ( var ( // hostExitCounter is a metric that tracks how many times the sentry // performed a host to guest world switch. - hostExitCounter = metric.MustCreateNewProfilingUint64Metric( + hostExitCounter = KVMProfiling.MustCreateNewUint64Metric( "/kvm/host_exits", false, "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 = metric.MustCreateNewProfilingUint64Metric( + userExitCounter = KVMProfiling.MustCreateNewUint64Metric( "/kvm/user_exits", false, "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 = metric.MustCreateNewProfilingUint64Metric( + interruptCounter = KVMProfiling.MustCreateNewUint64Metric( "/kvm/interrupts", false, "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 = metric.MustCreateNewProfilingUint64Metric( + mmapCallCounter = KVMProfiling.MustCreateNewUint64Metric( "/kvm/mmap_calls", false, "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 = metric.MustCreateNewProfilingUint64Metric( + 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)) // asInvalidateDuration are durations of calling addressSpace.invalidate(). - asInvalidateDuration = metric.MustCreateNewProfilingTimerMetric("/kvm/address_space_invalidate", + asInvalidateDuration = KVMProfiling.MustCreateNewTimerMetric("/kvm/address_space_invalidate", metric.NewExponentialBucketer(15, uint64(time.Nanosecond*100), 1, 2), "Duration of calling addressSpace.invalidate().") )