metric

package
v0.0.0-202406181927 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 18, 2024 License: Apache-2.0, MIT Imports: 23 Imported by: 0

Documentation

Overview

Package metric provides primitives for collecting metrics.

Index

Constants

View Source
const (

	// MetricsPrefix is prepended before every metrics line.
	MetricsPrefix = "GVISOR_METRICS\t"
	// MetricsHashIndicator is prepended before the hash of the metrics
	// data at the end of the metrics stream.
	MetricsHashIndicator = "ADLER32\t"
	// TimeColumn is the column header for the time column.
	TimeColumn = "Time (ns)"
	// MetricsMetaIndicator is prepended before every metrics metadata line
	// after metricsPrefix.
	MetricsMetaIndicator = "META\t"
	// MetricsStartTimeIndicator is prepended before the start time of the
	// metrics collection.
	MetricsStartTimeIndicator = "START_TIME\t"
)

Variables

View Source
var (
	// ErrNameInUse indicates that another metric is already defined for
	// the given name.
	ErrNameInUse = errors.New("metric name already in use")

	// ErrInitializationDone indicates that the caller tried to create a
	// new metric after initialization.
	ErrInitializationDone = errors.New("metric cannot be created after initialization is complete")

	// ErrFieldValueContainsIllegalChar indicates that the value of a metric
	// field had an invalid character in it.
	ErrFieldValueContainsIllegalChar = errors.New("metric field value contains illegal character")

	// ErrFieldHasNoAllowedValues indicates that the field needs to define some
	// allowed values to be a valid and useful field.
	ErrFieldHasNoAllowedValues = errors.New("metric field does not define any allowed values")

	// ErrTooManyFieldCombinations indicates that the number of unique
	// combinations of fields is too large to support.
	ErrTooManyFieldCombinations = errors.New("metric has too many combinations of allowed field values")
)
View Source
var (
	WeirdnessTypeTimeFallback         = FieldValue{"time_fallback"}
	WeirdnessTypePartialResult        = FieldValue{"partial_result"}
	WeirdnessTypeVsyscallCount        = FieldValue{"vsyscall_count"}
	WeirdnessTypeWatchdogStuckStartup = FieldValue{"watchdog_stuck_startup"}
	WeirdnessTypeWatchdogStuckTasks   = FieldValue{"watchdog_stuck_tasks"}
)

Weirdness metric type constants.

View Source
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, "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,
		))

	// 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, "Increment for suspicious operations such as opening an executable file to write from a gofer.",
		NewField("operation_type",
			&SuspiciousOperationsTypeOpenedWriteExecuteFile,
		))
)

List of global metrics that are used in multiple places.

View Source
var ErrNotYetInitialized = errors.New("metrics are not yet initialized")

ErrNotYetInitialized is returned by GetMetricRegistration if metrics are not yet initialized.

View Source
var SentryProfiling = FakeMetricBuilder{}

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.

View Source
var (
	SuspiciousOperationsTypeOpenedWriteExecuteFile = FieldValue{"opened_write_execute_file"}
)

Suspicious operations metric type constants.

Functions

func CheapNowNano

func CheapNowNano() int64

CheapNowNano returns the current unix timestamp in nanoseconds.

func Disable

func Disable() error

Disable sends an empty metric registration event over the event channel, disabling metric collection.

Precondition:

  • All metrics are registered.
  • Initialize/Disable has not been called.

func EmitMetricUpdate

func EmitMetricUpdate()

EmitMetricUpdate emits a MetricUpdate over the event channel.

Only metrics that have changed since the last call are emitted.

EmitMetricUpdate is thread-safe.

Preconditions:

  • Initialize has been called.

func GetMetricRegistration

func GetMetricRegistration() (*pb.MetricRegistration, error)

GetMetricRegistration returns the metric registration data for all registered metrics. Must be called after Initialize(). Returns ErrNotYetInitialized if metrics are not yet initialized.

func GetSnapshot

func GetSnapshot(options SnapshotOptions) (*prometheus.Snapshot, error)

GetSnapshot returns a Prometheus snapshot of the metric data. Returns ErrNotYetInitialized if metrics have not yet been initialized.

func Initialize

func Initialize() error

Initialize sends a metric registration event over the event channel.

Precondition:

  • All metrics are registered.
  • Initialize/Disable has not been called.

func MustRegisterCustomUint64Metric

func MustRegisterCustomUint64Metric(name string, cumulative, sync bool, description string, value func(...*FieldValue) uint64, fields ...Field)

MustRegisterCustomUint64Metric calls RegisterCustomUint64Metric for metrics without fields and panics if it returns an error.

func RegisterCustomUint64Metric

func RegisterCustomUint64Metric(name string, cumulative, sync bool, units pb.MetricMetadata_Units, description string, value func(...*FieldValue) uint64, fields ...Field) error

RegisterCustomUint64Metric registers a metric with the given name.

Register must only be called at init and will return and error if called after Initialized.

Preconditions:

  • name must be globally unique.
  • Initialize/Disable have not been called.
  • value is expected to accept exactly len(fields) arguments.

func StartProfilingMetrics

func StartProfilingMetrics[T ProfilingMetricsWriter](opts ProfilingMetricsOptions[T]) error

StartProfilingMetrics checks the ProfilingMetrics runsc flags and creates goroutines responsible for outputting the profiling metric data.

Preconditions:

  • All metrics are registered.
  • Initialize/Disable has been called.

func StartStage

func StartStage(stage InitStage) func()

StartStage should be called when an initialization stage is started. It returns a function that must be called to indicate that the stage ended. Alternatively, future calls to StartStage will implicitly indicate that the previous stage ended. Stage information will be emitted in the next call to EmitMetricUpdate after a stage has ended.

This function may (and is expected to) be called prior to final initialization of this metric library, as it has to capture early stages of Sentry initialization.

func StopProfilingMetrics

func StopProfilingMetrics()

StopProfilingMetrics stops the profiling metrics goroutines. Call to make sure all metric data has been flushed. Note that calling this function prior to StartProfilingMetrics has no effect.

Types

type Bucketer

type Bucketer interface {
	// NumFiniteBuckets is the number of finite buckets in the distribution.
	// This is only called once and never expected to return a different value.
	NumFiniteBuckets() int

	// LowerBound takes the index of a bucket (within [0, NumBuckets()]) and
	// returns the inclusive lower bound of that bucket.
	// In other words, the lowest value of `x` for which `BucketIndex(x) == i`
	// should be `x = LowerBound(i)`.
	// The upper bound of a bucket is the lower bound of the next bucket.
	// The last bucket (with `bucketIndex == NumFiniteBuckets()`) is infinite,
	// i.e. it has no upper bound (but it still has a lower bound).
	LowerBound(bucketIndex int) int64

	// BucketIndex takes a sample and returns the index of the bucket that the
	// sample should fall into.
	// Must return either:
	//   - A value within [0, NumBuckets() -1] if the sample falls within a
	//     finite bucket
	//   - NumBuckets() if the sample falls within the last (infinite) bucket
	//   - '-1' if the sample is lower than what any bucket can represent, i.e.
	//     the sample should be in the implicit "underflow" bucket.
	// This function must be go:nosplit-compatible and have no escapes.
	// +checkescape:all
	BucketIndex(sample int64) int
}

Bucketer is an interface to bucket values into finite, distinct buckets.

func NewDurationBucketer

func NewDurationBucketer(numFiniteBuckets int, minDuration, maxDuration time.Duration) Bucketer

NewDurationBucketer returns a Bucketer well-suited for measuring durations in nanoseconds. Useful for NewTimerMetric. minDuration and maxDuration are conservative estimates of the minimum and maximum durations expected to be accurately measured by the Bucketer.

type DistributionMetric

type DistributionMetric struct {
	// contains filtered or unexported fields
}

DistributionMetric represents a distribution of values in finite buckets. It also separately keeps track of min/max in order to ascertain whether the buckets can faithfully represent the range of values encountered in the distribution.

func MustCreateNewDistributionMetric

func MustCreateNewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) *DistributionMetric

MustCreateNewDistributionMetric creates and registers a distribution metric. If an error occurs, it panics.

func NewDistributionMetric

func NewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) (*DistributionMetric, error)

NewDistributionMetric creates and registers a new distribution metric.

func (*DistributionMetric) AddSample

func (d *DistributionMetric) AddSample(sample int64, fields ...*FieldValue)

AddSample adds a sample to the distribution. This *must* be called with the correct number of fields, or it will panic. +checkescape:all

type ExponentialBucketer

type ExponentialBucketer struct {
	// contains filtered or unexported fields
}

ExponentialBucketer implements Bucketer, with the first bucket starting with 0 as lowest bound with `Width` width, and each subsequent bucket being wider by a scaled exponentially-growing series, until `NumFiniteBuckets` buckets exist.

func NewExponentialBucketer

func NewExponentialBucketer(numFiniteBuckets int, width uint64, scale, growth float64) *ExponentialBucketer

NewExponentialBucketer returns a new Bucketer with exponential buckets.

func (*ExponentialBucketer) BucketIndex

func (b *ExponentialBucketer) BucketIndex(sample int64) int

BucketIndex implements Bucketer.BucketIndex. +checkescape:all

func (*ExponentialBucketer) LowerBound

func (b *ExponentialBucketer) LowerBound(bucketIndex int) int64

LowerBound implements Bucketer.LowerBound.

func (*ExponentialBucketer) NumFiniteBuckets

func (b *ExponentialBucketer) NumFiniteBuckets() int

NumFiniteBuckets implements Bucketer.NumFiniteBuckets.

type FakeDistributionMetric

type FakeDistributionMetric struct{}

FakeDistributionMetric is a type that implements all the methods of a DistributionMetric as a no-op.

func (*FakeDistributionMetric) AddSample

func (d *FakeDistributionMetric) AddSample(sample int64, fields ...*FieldValue)

AddSample on a FakeUint64Metric does nothing.

type FakeMetricBuilder

type FakeMetricBuilder struct{}

FakeMetricBuilder is a type used to produce conditionally compiled metrics. Methods of this struct produce fake, inactive metrics.

func (*FakeMetricBuilder) MustCreateNewDistributionMetric

func (b *FakeMetricBuilder) MustCreateNewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) *FakeDistributionMetric

MustCreateNewDistributionMetric creates a fake distribution metric.

func (*FakeMetricBuilder) MustCreateNewTimerMetric

func (b *FakeMetricBuilder) MustCreateNewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) *FakeTimerMetric

MustCreateNewTimerMetric creates a fake timer metric.

func (*FakeMetricBuilder) MustCreateNewUint64Metric

func (b *FakeMetricBuilder) MustCreateNewUint64Metric(name string, sync bool, description string, fields ...Field) *FakeUint64Metric

MustCreateNewUint64Metric creates a fake Uint64 metric.

func (*FakeMetricBuilder) NewDistributionMetric

func (b *FakeMetricBuilder) NewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) (*FakeDistributionMetric, error)

NewDistributionMetric creates a fake distribution metric.

func (*FakeMetricBuilder) NewTimerMetric

func (b *FakeMetricBuilder) NewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) (*FakeTimerMetric, error)

NewTimerMetric creates a fake timer metric.

func (*FakeMetricBuilder) NewUint64Metric

func (b *FakeMetricBuilder) NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*FakeUint64Metric, error)

NewUint64Metric creates a fake Uint64 metric.

type FakeTimedOperation

type FakeTimedOperation struct{}

FakeTimedOperation is a type that implements all the methods of a TimedOperation as a no-op.

func (FakeTimedOperation) Finish

func (o FakeTimedOperation) Finish(extraFields ...*FieldValue)

Finish on a FakeTimedOperation does nothing.

type FakeTimerMetric

type FakeTimerMetric struct{}

FakeTimerMetric is a type that implements all the methods of a TimerMetric as a no-op.

func (*FakeTimerMetric) Start

func (t *FakeTimerMetric) Start(fields ...*FieldValue) FakeTimedOperation

Start on a FakeUint64Metric returns a FakeTimedOperation struct, which does nothing and does not keep the time.

type FakeUint64Metric

type FakeUint64Metric struct{}

FakeUint64Metric is a type that implements all the methods of a Uint64Metric as a no-op.

func (*FakeUint64Metric) Increment

func (m *FakeUint64Metric) Increment(fieldValues ...*FieldValue)

Increment on a FakeUint64Metric does nothing.

func (*FakeUint64Metric) IncrementBy

func (m *FakeUint64Metric) IncrementBy(v uint64, fieldValues ...*FieldValue)

IncrementBy on a FakeUint64Metric does nothing.

func (*FakeUint64Metric) Value

func (m *FakeUint64Metric) Value(fieldValues ...*FieldValue) uint64

Value from a FakeUint64Metric always returns a meaningless value.

type Field

type Field struct {
	// contains filtered or unexported fields
}

Field contains the field name and allowed values for the metric which is used in registration of the metric.

func NewField

func NewField(name string, allowedValues ...*FieldValue) Field

NewField defines a new Field that can be used to break down a metric. The set of allowedValues must be unique strings wrapped with `FieldValue`. The *same* `FieldValue` pointers must be used during metric modifications. In practice, in most cases, this means you should declare these `FieldValue`s as package-level `var`s, and always use the address of these package-level `var`s during metric modifications.

type FieldValue

type FieldValue struct {
	Value string
}

FieldValue is a string that can be used as a value for a Field. It must be referred to by address when the Field is created and when its metric value is modified. This ensures that the same FieldValue reference is used, which in turn enables the metric code to use the address of a FieldValue as comparison operator, rather than doing string comparisons.

type InitStage

type InitStage string

InitStage is the name of a Sentry initialization stage.

var (
	InitRestoreConfig InitStage = "restore_config"
	InitExecConfig    InitStage = "exec_config"
	InitRestore       InitStage = "restore"
	InitCreateProcess InitStage = "create_process"
	InitTaskStart     InitStage = "task_start"
)

List of all Sentry initialization stages.

type ProfilingMetricsOptions

type ProfilingMetricsOptions[T ProfilingMetricsWriter] struct {
	// Sink is the sink to write the profiling metrics data to.
	Sink T

	// Lossy specifies whether the sink is lossy, i.e. data may be dropped from
	// too large logging volume. In this case, data integrity is desirable at the
	// expense of extra CPU cost at data-writing time. The data will be prefixed
	// with `MetricsPrefix` and the hash of the data will be appended at the end.
	Lossy bool

	// Metrics is the comma-separated list of metrics to profile.
	Metrics string

	// Rate is the rate at which the metrics are collected.
	Rate time.Duration
}

ProfilingMetricsOptions is the set of options to profile metrics.

type ProfilingMetricsWriter

type ProfilingMetricsWriter interface {
	// WriteString from the io.StringWriter interface.
	io.StringWriter

	// Close closes the writer.
	Close() error
}

ProfilingMetricsWriter is the interface for profiling metrics sinks.

type RealMetricBuilder

type RealMetricBuilder struct{}

RealMetricBuilder is a type used to produce conditionally compiled metrics. Methods of this struct produce real active metrics.

func (*RealMetricBuilder) MustCreateNewDistributionMetric

func (b *RealMetricBuilder) MustCreateNewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) *DistributionMetric

MustCreateNewDistributionMetric creates a real distribution metric or panics if unable to do so.

func (*RealMetricBuilder) MustCreateNewTimerMetric

func (b *RealMetricBuilder) MustCreateNewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) *TimerMetric

MustCreateNewTimerMetric creates a real timer metric or panics if unable to do so.

func (*RealMetricBuilder) MustCreateNewUint64Metric

func (b *RealMetricBuilder) MustCreateNewUint64Metric(name string, sync bool, description string, fields ...Field) *Uint64Metric

MustCreateNewUint64Metric creates a real Uint64 metric or panics if unable to do so.

func (*RealMetricBuilder) NewDistributionMetric

func (b *RealMetricBuilder) NewDistributionMetric(name string, sync bool, bucketer Bucketer, unit pb.MetricMetadata_Units, description string, fields ...Field) (*DistributionMetric, error)

NewDistributionMetric calls the generic metric.NewDistributionMetric to produce a real distribution metric.

func (*RealMetricBuilder) NewTimerMetric

func (b *RealMetricBuilder) NewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) (*TimerMetric, error)

NewTimerMetric calls the generic metric.NewTimerMetric to produce a real timer metric.

func (*RealMetricBuilder) NewUint64Metric

func (b *RealMetricBuilder) NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*Uint64Metric, error)

NewUint64Metric calls the generic metric.NewUint64Metric to produce a real Uint64 metric.

type SnapshotOptions

type SnapshotOptions struct {
	// Filter, if set, should return true for metrics that should be written to
	// the snapshot. If unset, all metrics are written to the snapshot.
	Filter func(*prometheus.Metric) bool
}

SnapshotOptions controls how snapshots are exported in GetSnapshot.

type TimedOperation

type TimedOperation struct {
	// contains filtered or unexported fields
}

TimedOperation is used by TimerMetric to keep track of the time elapsed between an operation starting and stopping.

func (TimedOperation) Finish

func (o TimedOperation) Finish(extraFields ...*FieldValue)

Finish marks an operation as finished and records its duration. `extraFields` is the rest of the fields appended to the fields passed to `TimerMetric.Start`. The concatenation of these two must be the exact number of fields that the underlying metric has. +checkescape:all

type TimerMetric

type TimerMetric struct {
	DistributionMetric
}

TimerMetric wraps a distribution metric with convenience functions for latency measurements, which is a popular specialization of distribution metrics.

func MustCreateNewTimerMetric

func MustCreateNewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) *TimerMetric

MustCreateNewTimerMetric creates and registers a timer metric. If an error occurs, it panics.

func NewTimerMetric

func NewTimerMetric(name string, nanoBucketer Bucketer, description string, fields ...Field) (*TimerMetric, error)

NewTimerMetric provides a convenient way to measure latencies. The arguments are the same as `NewDistributionMetric`, except:

  • `nanoBucketer`: Same as `NewDistribution`'s `bucketer`, expected to hold durations in nanoseconds. Adjust parameters accordingly. NewDurationBucketer may be helpful here.

func (*TimerMetric) Start

func (t *TimerMetric) Start(fields ...*FieldValue) TimedOperation

Start starts a timer measurement for the given combination of fields. It returns a TimedOperation which can be passed around as necessary to measure the duration of the operation. Once the operation is finished, call Finish on the TimedOperation. The fields passed to Start may be partially specified; if so, the remaining fields must be passed to TimedOperation.Finish. This is useful for cases where which path an operation took is only known after it happens. This path can be part of the fields passed to Finish. +checkescape:all

type Uint64Metric

type Uint64Metric struct {
	// contains filtered or unexported fields
}

Uint64Metric encapsulates a uint64 that represents some kind of metric to be monitored.

Metrics are not saved across save/restore and thus reset to zero on restore.

func MustCreateNewUint64Metric

func MustCreateNewUint64Metric(name string, sync bool, description string, fields ...Field) *Uint64Metric

MustCreateNewUint64Metric calls NewUint64Metric and panics if it returns an error.

func MustCreateNewUint64NanosecondsMetric

func MustCreateNewUint64NanosecondsMetric(name string, sync bool, description string) *Uint64Metric

MustCreateNewUint64NanosecondsMetric calls NewUint64Metric and panics if it returns an error.

func NewUint64Metric

func NewUint64Metric(name string, sync bool, units pb.MetricMetadata_Units, description string, fields ...Field) (*Uint64Metric, error)

NewUint64Metric creates and registers a new cumulative metric with the given name.

Metrics must be statically defined (i.e., at init).

func (*Uint64Metric) Increment

func (m *Uint64Metric) Increment(fieldValues ...*FieldValue)

Increment increments the metric field by 1. This must be called with the correct number of field values or it will panic.

func (*Uint64Metric) IncrementBy

func (m *Uint64Metric) IncrementBy(v uint64, fieldValues ...*FieldValue)

IncrementBy increments the metric by v. This must be called with the correct number of field values or it will panic.

func (*Uint64Metric) Value

func (m *Uint64Metric) Value(fieldValues ...*FieldValue) uint64

Value returns the current value of the metric for the given set of fields. This must be called with the correct number of field values or it will panic.

Directories

Path Synopsis
buckettool prints buckets for distribution metrics.
buckettool prints buckets for distribution metrics.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL