summaryrefslogtreecommitdiff
path: root/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar')
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/doc.go6
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/drop.go23
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/exemplar.go29
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filter.go29
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filtered_reservoir.go49
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/hist.go46
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/rand.go191
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/reservoir.go32
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/storage.go95
-rw-r--r--vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/value.go58
10 files changed, 0 insertions, 558 deletions
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/doc.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/doc.go
deleted file mode 100644
index 5394f48e0..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/doc.go
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-// Package exemplar provides an implementation of the OpenTelemetry exemplar
-// reservoir to be used in metric collection pipelines.
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/drop.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/drop.go
deleted file mode 100644
index 5a0f39ae1..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/drop.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "context"
-
- "go.opentelemetry.io/otel/attribute"
-)
-
-// Drop returns a [FilteredReservoir] that drops all measurements it is offered.
-func Drop[N int64 | float64]() FilteredReservoir[N] { return &dropRes[N]{} }
-
-type dropRes[N int64 | float64] struct{}
-
-// Offer does nothing, all measurements offered will be dropped.
-func (r *dropRes[N]) Offer(context.Context, N, []attribute.KeyValue) {}
-
-// Collect resets dest. No exemplars will ever be returned.
-func (r *dropRes[N]) Collect(dest *[]Exemplar) {
- *dest = (*dest)[:0]
-}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/exemplar.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/exemplar.go
deleted file mode 100644
index fcaa6a469..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/exemplar.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "time"
-
- "go.opentelemetry.io/otel/attribute"
-)
-
-// Exemplar is a measurement sampled from a timeseries providing a typical
-// example.
-type Exemplar struct {
- // FilteredAttributes are the attributes recorded with the measurement but
- // filtered out of the timeseries' aggregated data.
- FilteredAttributes []attribute.KeyValue
- // Time is the time when the measurement was recorded.
- Time time.Time
- // Value is the measured value.
- Value Value
- // SpanID is the ID of the span that was active during the measurement. If
- // no span was active or the span was not sampled this will be empty.
- SpanID []byte `json:",omitempty"`
- // TraceID is the ID of the trace the active span belonged to during the
- // measurement. If no span was active or the span was not sampled this will
- // be empty.
- TraceID []byte `json:",omitempty"`
-}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filter.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filter.go
deleted file mode 100644
index 152a069a0..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filter.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "context"
-
- "go.opentelemetry.io/otel/trace"
-)
-
-// Filter determines if a measurement should be offered.
-//
-// The passed ctx needs to contain any baggage or span that were active
-// when the measurement was made. This information may be used by the
-// Reservoir in making a sampling decision.
-type Filter func(context.Context) bool
-
-// SampledFilter is a [Filter] that will only offer measurements
-// if the passed context associated with the measurement contains a sampled
-// [go.opentelemetry.io/otel/trace.SpanContext].
-func SampledFilter(ctx context.Context) bool {
- return trace.SpanContextFromContext(ctx).IsSampled()
-}
-
-// AlwaysOnFilter is a [Filter] that always offers measurements.
-func AlwaysOnFilter(ctx context.Context) bool {
- return true
-}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filtered_reservoir.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filtered_reservoir.go
deleted file mode 100644
index 9fedfa4be..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/filtered_reservoir.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "context"
- "time"
-
- "go.opentelemetry.io/otel/attribute"
-)
-
-// FilteredReservoir wraps a [Reservoir] with a filter.
-type FilteredReservoir[N int64 | float64] interface {
- // Offer accepts the parameters associated with a measurement. The
- // parameters will be stored as an exemplar if the filter decides to
- // sample the measurement.
- //
- // The passed ctx needs to contain any baggage or span that were active
- // when the measurement was made. This information may be used by the
- // Reservoir in making a sampling decision.
- Offer(ctx context.Context, val N, attr []attribute.KeyValue)
- // Collect returns all the held exemplars in the reservoir.
- Collect(dest *[]Exemplar)
-}
-
-// filteredReservoir handles the pre-sampled exemplar of measurements made.
-type filteredReservoir[N int64 | float64] struct {
- filter Filter
- reservoir Reservoir
-}
-
-// NewFilteredReservoir creates a [FilteredReservoir] which only offers values
-// that are allowed by the filter.
-func NewFilteredReservoir[N int64 | float64](f Filter, r Reservoir) FilteredReservoir[N] {
- return &filteredReservoir[N]{
- filter: f,
- reservoir: r,
- }
-}
-
-func (f *filteredReservoir[N]) Offer(ctx context.Context, val N, attr []attribute.KeyValue) {
- if f.filter(ctx) {
- // only record the current time if we are sampling this measurment.
- f.reservoir.Offer(ctx, time.Now(), NewValue(val), attr)
- }
-}
-
-func (f *filteredReservoir[N]) Collect(dest *[]Exemplar) { f.reservoir.Collect(dest) }
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/hist.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/hist.go
deleted file mode 100644
index a6ff86d02..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/hist.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "context"
- "slices"
- "sort"
- "time"
-
- "go.opentelemetry.io/otel/attribute"
-)
-
-// Histogram returns a [Reservoir] that samples the last measurement that falls
-// within a histogram bucket. The histogram bucket upper-boundaries are define
-// by bounds.
-//
-// The passed bounds will be sorted by this function.
-func Histogram(bounds []float64) Reservoir {
- slices.Sort(bounds)
- return &histRes{
- bounds: bounds,
- storage: newStorage(len(bounds) + 1),
- }
-}
-
-type histRes struct {
- *storage
-
- // bounds are bucket bounds in ascending order.
- bounds []float64
-}
-
-func (r *histRes) Offer(ctx context.Context, t time.Time, v Value, a []attribute.KeyValue) {
- var x float64
- switch v.Type() {
- case Int64ValueType:
- x = float64(v.Int64())
- case Float64ValueType:
- x = v.Float64()
- default:
- panic("unknown value type")
- }
- r.store[sort.SearchFloat64s(r.bounds, x)] = newMeasurement(ctx, t, v, a)
-}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/rand.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/rand.go
deleted file mode 100644
index 199a2608f..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/rand.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "context"
- "math"
- "math/rand"
- "sync"
- "time"
-
- "go.opentelemetry.io/otel/attribute"
-)
-
-var (
- // rng is used to make sampling decisions.
- //
- // Do not use crypto/rand. There is no reason for the decrease in performance
- // given this is not a security sensitive decision.
- rng = rand.New(rand.NewSource(time.Now().UnixNano()))
- // Ensure concurrent safe accecess to rng and its underlying source.
- rngMu sync.Mutex
-)
-
-// random returns, as a float64, a uniform pseudo-random number in the open
-// interval (0.0,1.0).
-func random() float64 {
- // TODO: This does not return a uniform number. rng.Float64 returns a
- // uniformly random int in [0,2^53) that is divided by 2^53. Meaning it
- // returns multiples of 2^-53, and not all floating point numbers between 0
- // and 1 (i.e. for values less than 2^-4 the 4 last bits of the significand
- // are always going to be 0).
- //
- // An alternative algorithm should be considered that will actually return
- // a uniform number in the interval (0,1). For example, since the default
- // rand source provides a uniform distribution for Int63, this can be
- // converted following the prototypical code of Mersenne Twister 64 (Takuji
- // Nishimura and Makoto Matsumoto:
- // http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/VERSIONS/C-LANG/mt19937-64.c)
- //
- // (float64(rng.Int63()>>11) + 0.5) * (1.0 / 4503599627370496.0)
- //
- // There are likely many other methods to explore here as well.
-
- rngMu.Lock()
- defer rngMu.Unlock()
-
- f := rng.Float64()
- for f == 0 {
- f = rng.Float64()
- }
- return f
-}
-
-// FixedSize returns a [Reservoir] that samples at most k exemplars. If there
-// are k or less measurements made, the Reservoir will sample each one. If
-// there are more than k, the Reservoir will then randomly sample all
-// additional measurement with a decreasing probability.
-func FixedSize(k int) Reservoir {
- r := &randRes{storage: newStorage(k)}
- r.reset()
- return r
-}
-
-type randRes struct {
- *storage
-
- // count is the number of measurement seen.
- count int64
- // next is the next count that will store a measurement at a random index
- // once the reservoir has been filled.
- next int64
- // w is the largest random number in a distribution that is used to compute
- // the next next.
- w float64
-}
-
-func (r *randRes) Offer(ctx context.Context, t time.Time, n Value, a []attribute.KeyValue) {
- // The following algorithm is "Algorithm L" from Li, Kim-Hung (4 December
- // 1994). "Reservoir-Sampling Algorithms of Time Complexity
- // O(n(1+log(N/n)))". ACM Transactions on Mathematical Software. 20 (4):
- // 481–493 (https://dl.acm.org/doi/10.1145/198429.198435).
- //
- // A high-level overview of "Algorithm L":
- // 0) Pre-calculate the random count greater than the storage size when
- // an exemplar will be replaced.
- // 1) Accept all measurements offered until the configured storage size is
- // reached.
- // 2) Loop:
- // a) When the pre-calculate count is reached, replace a random
- // existing exemplar with the offered measurement.
- // b) Calculate the next random count greater than the existing one
- // which will replace another exemplars
- //
- // The way a "replacement" count is computed is by looking at `n` number of
- // independent random numbers each corresponding to an offered measurement.
- // Of these numbers the smallest `k` (the same size as the storage
- // capacity) of them are kept as a subset. The maximum value in this
- // subset, called `w` is used to weight another random number generation
- // for the next count that will be considered.
- //
- // By weighting the next count computation like described, it is able to
- // perform a uniformly-weighted sampling algorithm based on the number of
- // samples the reservoir has seen so far. The sampling will "slow down" as
- // more and more samples are offered so as to reduce a bias towards those
- // offered just prior to the end of the collection.
- //
- // This algorithm is preferred because of its balance of simplicity and
- // performance. It will compute three random numbers (the bulk of
- // computation time) for each item that becomes part of the reservoir, but
- // it does not spend any time on items that do not. In particular it has an
- // asymptotic runtime of O(k(1 + log(n/k)) where n is the number of
- // measurements offered and k is the reservoir size.
- //
- // See https://en.wikipedia.org/wiki/Reservoir_sampling for an overview of
- // this and other reservoir sampling algorithms. See
- // https://github.com/MrAlias/reservoir-sampling for a performance
- // comparison of reservoir sampling algorithms.
-
- if int(r.count) < cap(r.store) {
- r.store[r.count] = newMeasurement(ctx, t, n, a)
- } else {
- if r.count == r.next {
- // Overwrite a random existing measurement with the one offered.
- idx := int(rng.Int63n(int64(cap(r.store))))
- r.store[idx] = newMeasurement(ctx, t, n, a)
- r.advance()
- }
- }
- r.count++
-}
-
-// reset resets r to the initial state.
-func (r *randRes) reset() {
- // This resets the number of exemplars known.
- r.count = 0
- // Random index inserts should only happen after the storage is full.
- r.next = int64(cap(r.store))
-
- // Initial random number in the series used to generate r.next.
- //
- // This is set before r.advance to reset or initialize the random number
- // series. Without doing so it would always be 0 or never restart a new
- // random number series.
- //
- // This maps the uniform random number in (0,1) to a geometric distribution
- // over the same interval. The mean of the distribution is inversely
- // proportional to the storage capacity.
- r.w = math.Exp(math.Log(random()) / float64(cap(r.store)))
-
- r.advance()
-}
-
-// advance updates the count at which the offered measurement will overwrite an
-// existing exemplar.
-func (r *randRes) advance() {
- // Calculate the next value in the random number series.
- //
- // The current value of r.w is based on the max of a distribution of random
- // numbers (i.e. `w = max(u_1,u_2,...,u_k)` for `k` equal to the capacity
- // of the storage and each `u` in the interval (0,w)). To calculate the
- // next r.w we use the fact that when the next exemplar is selected to be
- // included in the storage an existing one will be dropped, and the
- // corresponding random number in the set used to calculate r.w will also
- // be replaced. The replacement random number will also be within (0,w),
- // therefore the next r.w will be based on the same distribution (i.e.
- // `max(u_1,u_2,...,u_k)`). Therefore, we can sample the next r.w by
- // computing the next random number `u` and take r.w as `w * u^(1/k)`.
- r.w *= math.Exp(math.Log(random()) / float64(cap(r.store)))
- // Use the new random number in the series to calculate the count of the
- // next measurement that will be stored.
- //
- // Given 0 < r.w < 1, each iteration will result in subsequent r.w being
- // smaller. This translates here into the next next being selected against
- // a distribution with a higher mean (i.e. the expected value will increase
- // and replacements become less likely)
- //
- // Important to note, the new r.next will always be at least 1 more than
- // the last r.next.
- r.next += int64(math.Log(random())/math.Log(1-r.w)) + 1
-}
-
-func (r *randRes) Collect(dest *[]Exemplar) {
- r.storage.Collect(dest)
- // Call reset here even though it will reset r.count and restart the random
- // number series. This will persist any old exemplars as long as no new
- // measurements are offered, but it will also prioritize those new
- // measurements that are made over the older collection cycle ones.
- r.reset()
-}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/reservoir.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/reservoir.go
deleted file mode 100644
index 80fa59554..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/reservoir.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "context"
- "time"
-
- "go.opentelemetry.io/otel/attribute"
-)
-
-// Reservoir holds the sampled exemplar of measurements made.
-type Reservoir interface {
- // Offer accepts the parameters associated with a measurement. The
- // parameters will be stored as an exemplar if the Reservoir decides to
- // sample the measurement.
- //
- // The passed ctx needs to contain any baggage or span that were active
- // when the measurement was made. This information may be used by the
- // Reservoir in making a sampling decision.
- //
- // The time t is the time when the measurement was made. The val and attr
- // parameters are the value and dropped (filtered) attributes of the
- // measurement respectively.
- Offer(ctx context.Context, t time.Time, val Value, attr []attribute.KeyValue)
-
- // Collect returns all the held exemplars.
- //
- // The Reservoir state is preserved after this call.
- Collect(dest *[]Exemplar)
-}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/storage.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/storage.go
deleted file mode 100644
index 10b2976f7..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/storage.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import (
- "context"
- "time"
-
- "go.opentelemetry.io/otel/attribute"
- "go.opentelemetry.io/otel/trace"
-)
-
-// storage is an exemplar storage for [Reservoir] implementations.
-type storage struct {
- // store are the measurements sampled.
- //
- // This does not use []metricdata.Exemplar because it potentially would
- // require an allocation for trace and span IDs in the hot path of Offer.
- store []measurement
-}
-
-func newStorage(n int) *storage {
- return &storage{store: make([]measurement, n)}
-}
-
-// Collect returns all the held exemplars.
-//
-// The Reservoir state is preserved after this call.
-func (r *storage) Collect(dest *[]Exemplar) {
- *dest = reset(*dest, len(r.store), len(r.store))
- var n int
- for _, m := range r.store {
- if !m.valid {
- continue
- }
-
- m.Exemplar(&(*dest)[n])
- n++
- }
- *dest = (*dest)[:n]
-}
-
-// measurement is a measurement made by a telemetry system.
-type measurement struct {
- // FilteredAttributes are the attributes dropped during the measurement.
- FilteredAttributes []attribute.KeyValue
- // Time is the time when the measurement was made.
- Time time.Time
- // Value is the value of the measurement.
- Value Value
- // SpanContext is the SpanContext active when a measurement was made.
- SpanContext trace.SpanContext
-
- valid bool
-}
-
-// newMeasurement returns a new non-empty Measurement.
-func newMeasurement(ctx context.Context, ts time.Time, v Value, droppedAttr []attribute.KeyValue) measurement {
- return measurement{
- FilteredAttributes: droppedAttr,
- Time: ts,
- Value: v,
- SpanContext: trace.SpanContextFromContext(ctx),
- valid: true,
- }
-}
-
-// Exemplar returns m as an [Exemplar].
-func (m measurement) Exemplar(dest *Exemplar) {
- dest.FilteredAttributes = m.FilteredAttributes
- dest.Time = m.Time
- dest.Value = m.Value
-
- if m.SpanContext.HasTraceID() {
- traceID := m.SpanContext.TraceID()
- dest.TraceID = traceID[:]
- } else {
- dest.TraceID = dest.TraceID[:0]
- }
-
- if m.SpanContext.HasSpanID() {
- spanID := m.SpanContext.SpanID()
- dest.SpanID = spanID[:]
- } else {
- dest.SpanID = dest.SpanID[:0]
- }
-}
-
-func reset[T any](s []T, length, capacity int) []T {
- if cap(s) < capacity {
- return make([]T, length, capacity)
- }
- return s[:length]
-}
diff --git a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/value.go b/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/value.go
deleted file mode 100644
index 1957d6b1e..000000000
--- a/vendor/go.opentelemetry.io/otel/sdk/metric/internal/exemplar/value.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-package exemplar // import "go.opentelemetry.io/otel/sdk/metric/internal/exemplar"
-
-import "math"
-
-// ValueType identifies the type of value used in exemplar data.
-type ValueType uint8
-
-const (
- // UnknownValueType should not be used. It represents a misconfigured
- // Value.
- UnknownValueType ValueType = 0
- // Int64ValueType represents a Value with int64 data.
- Int64ValueType ValueType = 1
- // Float64ValueType represents a Value with float64 data.
- Float64ValueType ValueType = 2
-)
-
-// Value is the value of data held by an exemplar.
-type Value struct {
- t ValueType
- val uint64
-}
-
-// NewValue returns a new [Value] for the provided value.
-func NewValue[N int64 | float64](value N) Value {
- switch v := any(value).(type) {
- case int64:
- return Value{t: Int64ValueType, val: uint64(v)}
- case float64:
- return Value{t: Float64ValueType, val: math.Float64bits(v)}
- }
- return Value{}
-}
-
-// Type returns the [ValueType] of data held by v.
-func (v Value) Type() ValueType { return v.t }
-
-// Int64 returns the value of v as an int64. If the ValueType of v is not an
-// Int64ValueType, 0 is returned.
-func (v Value) Int64() int64 {
- if v.t == Int64ValueType {
- // Assumes the correct int64 was stored in v.val based on type.
- return int64(v.val) // nolint: gosec
- }
- return 0
-}
-
-// Float64 returns the value of v as an float64. If the ValueType of v is not
-// an Float64ValueType, 0 is returned.
-func (v Value) Float64() float64 {
- if v.t == Float64ValueType {
- return math.Float64frombits(v.val)
- }
- return 0
-}