aboutsummaryrefslogtreecommitdiffstats
path: root/library/go/core/metrics
diff options
context:
space:
mode:
authorqrort <qrort@yandex-team.com>2022-12-02 11:31:25 +0300
committerqrort <qrort@yandex-team.com>2022-12-02 11:31:25 +0300
commitb1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806 (patch)
tree2a23209faf0fea5586a6d4b9cee60d1b318d29fe /library/go/core/metrics
parent559174a9144de40d6bb3997ea4073c82289b4974 (diff)
downloadydb-b1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806.tar.gz
remove kikimr/driver DEPENDS
Diffstat (limited to 'library/go/core/metrics')
-rw-r--r--library/go/core/metrics/buckets.go147
-rw-r--r--library/go/core/metrics/collect/collect.go9
-rw-r--r--library/go/core/metrics/collect/system.go229
-rw-r--r--library/go/core/metrics/internal/pkg/metricsutil/buckets.go27
-rw-r--r--library/go/core/metrics/internal/pkg/registryutil/registryutil.go104
-rw-r--r--library/go/core/metrics/metrics.go140
-rw-r--r--library/go/core/metrics/solomon/converter.go73
-rw-r--r--library/go/core/metrics/solomon/counter.go98
-rw-r--r--library/go/core/metrics/solomon/func_counter.go86
-rw-r--r--library/go/core/metrics/solomon/func_gauge.go87
-rw-r--r--library/go/core/metrics/solomon/gauge.go116
-rw-r--r--library/go/core/metrics/solomon/histogram.go177
-rw-r--r--library/go/core/metrics/solomon/metrics.go178
-rw-r--r--library/go/core/metrics/solomon/metrics_opts.go29
-rw-r--r--library/go/core/metrics/solomon/registry.go221
-rw-r--r--library/go/core/metrics/solomon/registry_opts.go87
-rw-r--r--library/go/core/metrics/solomon/spack.go340
-rw-r--r--library/go/core/metrics/solomon/spack_compression.go162
-rw-r--r--library/go/core/metrics/solomon/stream.go89
-rw-r--r--library/go/core/metrics/solomon/timer.go92
-rw-r--r--library/go/core/metrics/solomon/vec.go226
21 files changed, 0 insertions, 2717 deletions
diff --git a/library/go/core/metrics/buckets.go b/library/go/core/metrics/buckets.go
deleted file mode 100644
index 063c0c4418..0000000000
--- a/library/go/core/metrics/buckets.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package metrics
-
-import (
- "sort"
- "time"
-)
-
-var (
- _ DurationBuckets = (*durationBuckets)(nil)
- _ Buckets = (*buckets)(nil)
-)
-
-const (
- errBucketsCountNeedsGreaterThanZero = "n needs to be > 0"
- errBucketsStartNeedsGreaterThanZero = "start needs to be > 0"
- errBucketsFactorNeedsGreaterThanOne = "factor needs to be > 1"
-)
-
-type durationBuckets struct {
- buckets []time.Duration
-}
-
-// NewDurationBuckets returns new DurationBuckets implementation.
-func NewDurationBuckets(bk ...time.Duration) DurationBuckets {
- sort.Slice(bk, func(i, j int) bool {
- return bk[i] < bk[j]
- })
- return durationBuckets{buckets: bk}
-}
-
-func (d durationBuckets) Size() int {
- return len(d.buckets)
-}
-
-func (d durationBuckets) MapDuration(dv time.Duration) (idx int) {
- for _, bound := range d.buckets {
- if dv < bound {
- break
- }
- idx++
- }
- return
-}
-
-func (d durationBuckets) UpperBound(idx int) time.Duration {
- if idx > d.Size()-1 {
- panic("idx is out of bounds")
- }
- return d.buckets[idx]
-}
-
-type buckets struct {
- buckets []float64
-}
-
-// NewBuckets returns new Buckets implementation.
-func NewBuckets(bk ...float64) Buckets {
- sort.Slice(bk, func(i, j int) bool {
- return bk[i] < bk[j]
- })
- return buckets{buckets: bk}
-}
-
-func (d buckets) Size() int {
- return len(d.buckets)
-}
-
-func (d buckets) MapValue(v float64) (idx int) {
- for _, bound := range d.buckets {
- if v < bound {
- break
- }
- idx++
- }
- return
-}
-
-func (d buckets) UpperBound(idx int) float64 {
- if idx > d.Size()-1 {
- panic("idx is out of bounds")
- }
- return d.buckets[idx]
-}
-
-// MakeLinearBuckets creates a set of linear value buckets.
-func MakeLinearBuckets(start, width float64, n int) Buckets {
- if n <= 0 {
- panic(errBucketsCountNeedsGreaterThanZero)
- }
- bounds := make([]float64, n)
- for i := range bounds {
- bounds[i] = start + (float64(i) * width)
- }
- return NewBuckets(bounds...)
-}
-
-// MakeLinearDurationBuckets creates a set of linear duration buckets.
-func MakeLinearDurationBuckets(start, width time.Duration, n int) DurationBuckets {
- if n <= 0 {
- panic(errBucketsCountNeedsGreaterThanZero)
- }
- buckets := make([]time.Duration, n)
- for i := range buckets {
- buckets[i] = start + (time.Duration(i) * width)
- }
- return NewDurationBuckets(buckets...)
-}
-
-// MakeExponentialBuckets creates a set of exponential value buckets.
-func MakeExponentialBuckets(start, factor float64, n int) Buckets {
- if n <= 0 {
- panic(errBucketsCountNeedsGreaterThanZero)
- }
- if start <= 0 {
- panic(errBucketsStartNeedsGreaterThanZero)
- }
- if factor <= 1 {
- panic(errBucketsFactorNeedsGreaterThanOne)
- }
- buckets := make([]float64, n)
- curr := start
- for i := range buckets {
- buckets[i] = curr
- curr *= factor
- }
- return NewBuckets(buckets...)
-}
-
-// MakeExponentialDurationBuckets creates a set of exponential duration buckets.
-func MakeExponentialDurationBuckets(start time.Duration, factor float64, n int) DurationBuckets {
- if n <= 0 {
- panic(errBucketsCountNeedsGreaterThanZero)
- }
- if start <= 0 {
- panic(errBucketsStartNeedsGreaterThanZero)
- }
- if factor <= 1 {
- panic(errBucketsFactorNeedsGreaterThanOne)
- }
- buckets := make([]time.Duration, n)
- curr := start
- for i := range buckets {
- buckets[i] = curr
- curr = time.Duration(float64(curr) * factor)
- }
- return NewDurationBuckets(buckets...)
-}
diff --git a/library/go/core/metrics/collect/collect.go b/library/go/core/metrics/collect/collect.go
deleted file mode 100644
index 3abbbcdfa9..0000000000
--- a/library/go/core/metrics/collect/collect.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package collect
-
-import (
- "context"
-
- "a.yandex-team.ru/library/go/core/metrics"
-)
-
-type Func func(ctx context.Context, r metrics.Registry, c metrics.CollectPolicy)
diff --git a/library/go/core/metrics/collect/system.go b/library/go/core/metrics/collect/system.go
deleted file mode 100644
index 8ce89ebc05..0000000000
--- a/library/go/core/metrics/collect/system.go
+++ /dev/null
@@ -1,229 +0,0 @@
-package collect
-
-import (
- "context"
- "os"
- "runtime"
- "runtime/debug"
- "time"
-
- "github.com/prometheus/procfs"
-
- "a.yandex-team.ru/library/go/core/buildinfo"
- "a.yandex-team.ru/library/go/core/metrics"
-)
-
-var _ Func = GoMetrics
-
-func GoMetrics(_ context.Context, r metrics.Registry, c metrics.CollectPolicy) {
- if r == nil {
- return
- }
- r = r.WithPrefix("go")
-
- var stats debug.GCStats
- stats.PauseQuantiles = make([]time.Duration, 5) // Minimum, 25%, 50%, 75%, and maximum pause times.
- var numGoroutine, numThread int
- var ms runtime.MemStats
-
- c.AddCollect(func(context.Context) {
- debug.ReadGCStats(&stats)
- runtime.ReadMemStats(&ms)
-
- numThread, _ = runtime.ThreadCreateProfile(nil)
- numGoroutine = runtime.NumGoroutine()
- })
-
- gcRegistry := r.WithPrefix("gc")
- gcRegistry.FuncCounter("num", c.RegisteredCounter(func() int64 {
- return stats.NumGC
- }))
- gcRegistry.FuncCounter(r.ComposeName("pause", "total", "ns"), c.RegisteredCounter(func() int64 {
- return stats.PauseTotal.Nanoseconds()
- }))
- gcRegistry.FuncGauge(r.ComposeName("pause", "quantile", "min"), c.RegisteredGauge(func() float64 {
- return stats.PauseQuantiles[0].Seconds()
- }))
- gcRegistry.FuncGauge(r.ComposeName("pause", "quantile", "25"), c.RegisteredGauge(func() float64 {
- return stats.PauseQuantiles[1].Seconds()
- }))
- gcRegistry.FuncGauge(r.ComposeName("pause", "quantile", "50"), c.RegisteredGauge(func() float64 {
- return stats.PauseQuantiles[2].Seconds()
- }))
- gcRegistry.FuncGauge(r.ComposeName("pause", "quantile", "75"), c.RegisteredGauge(func() float64 {
- return stats.PauseQuantiles[3].Seconds()
- }))
- gcRegistry.FuncGauge(r.ComposeName("pause", "quantile", "max"), c.RegisteredGauge(func() float64 {
- return stats.PauseQuantiles[4].Seconds()
- }))
- gcRegistry.FuncGauge(r.ComposeName("last", "ts"), c.RegisteredGauge(func() float64 {
- return float64(ms.LastGC)
- }))
- gcRegistry.FuncCounter(r.ComposeName("forced", "num"), c.RegisteredCounter(func() int64 {
- return int64(ms.NumForcedGC)
- }))
-
- r.FuncGauge(r.ComposeName("goroutine", "num"), c.RegisteredGauge(func() float64 {
- return float64(numGoroutine)
- }))
- r.FuncGauge(r.ComposeName("thread", "num"), c.RegisteredGauge(func() float64 {
- return float64(numThread)
- }))
-
- memRegistry := r.WithPrefix("mem")
- memRegistry.FuncCounter(r.ComposeName("alloc", "total"), c.RegisteredCounter(func() int64 {
- return int64(ms.TotalAlloc)
- }))
- memRegistry.FuncGauge("sys", c.RegisteredGauge(func() float64 {
- return float64(ms.Sys)
- }))
- memRegistry.FuncCounter("lookups", c.RegisteredCounter(func() int64 {
- return int64(ms.Lookups)
- }))
- memRegistry.FuncCounter("mallocs", c.RegisteredCounter(func() int64 {
- return int64(ms.Mallocs)
- }))
- memRegistry.FuncCounter("frees", c.RegisteredCounter(func() int64 {
- return int64(ms.Frees)
- }))
- memRegistry.FuncGauge(r.ComposeName("heap", "alloc"), c.RegisteredGauge(func() float64 {
- return float64(ms.HeapAlloc)
- }))
- memRegistry.FuncGauge(r.ComposeName("heap", "sys"), c.RegisteredGauge(func() float64 {
- return float64(ms.HeapSys)
- }))
- memRegistry.FuncGauge(r.ComposeName("heap", "idle"), c.RegisteredGauge(func() float64 {
- return float64(ms.HeapIdle)
- }))
- memRegistry.FuncGauge(r.ComposeName("heap", "inuse"), c.RegisteredGauge(func() float64 {
- return float64(ms.HeapInuse)
- }))
- memRegistry.FuncGauge(r.ComposeName("heap", "released"), c.RegisteredGauge(func() float64 {
- return float64(ms.HeapReleased)
- }))
- memRegistry.FuncGauge(r.ComposeName("heap", "objects"), c.RegisteredGauge(func() float64 {
- return float64(ms.HeapObjects)
- }))
-
- memRegistry.FuncGauge(r.ComposeName("stack", "inuse"), c.RegisteredGauge(func() float64 {
- return float64(ms.StackInuse)
- }))
- memRegistry.FuncGauge(r.ComposeName("stack", "sys"), c.RegisteredGauge(func() float64 {
- return float64(ms.StackSys)
- }))
-
- memRegistry.FuncGauge(r.ComposeName("span", "inuse"), c.RegisteredGauge(func() float64 {
- return float64(ms.MSpanInuse)
- }))
- memRegistry.FuncGauge(r.ComposeName("span", "sys"), c.RegisteredGauge(func() float64 {
- return float64(ms.MSpanSys)
- }))
-
- memRegistry.FuncGauge(r.ComposeName("cache", "inuse"), c.RegisteredGauge(func() float64 {
- return float64(ms.MCacheInuse)
- }))
- memRegistry.FuncGauge(r.ComposeName("cache", "sys"), c.RegisteredGauge(func() float64 {
- return float64(ms.MCacheSys)
- }))
-
- memRegistry.FuncGauge(r.ComposeName("buck", "hash", "sys"), c.RegisteredGauge(func() float64 {
- return float64(ms.BuckHashSys)
- }))
- memRegistry.FuncGauge(r.ComposeName("gc", "sys"), c.RegisteredGauge(func() float64 {
- return float64(ms.GCSys)
- }))
- memRegistry.FuncGauge(r.ComposeName("other", "sys"), c.RegisteredGauge(func() float64 {
- return float64(ms.OtherSys)
- }))
- memRegistry.FuncGauge(r.ComposeName("gc", "next"), c.RegisteredGauge(func() float64 {
- return float64(ms.NextGC)
- }))
-
- memRegistry.FuncGauge(r.ComposeName("gc", "cpu", "fraction"), c.RegisteredGauge(func() float64 {
- return ms.GCCPUFraction
- }))
-}
-
-var _ Func = ProcessMetrics
-
-func ProcessMetrics(_ context.Context, r metrics.Registry, c metrics.CollectPolicy) {
- if r == nil {
- return
- }
- buildVersion := buildinfo.Info.ArcadiaSourceRevision
- r.WithTags(map[string]string{"revision": buildVersion}).Gauge("build").Set(1.0)
-
- pid := os.Getpid()
- proc, err := procfs.NewProc(pid)
- if err != nil {
- return
- }
-
- procRegistry := r.WithPrefix("proc")
-
- var ioStat procfs.ProcIO
- var procStat procfs.ProcStat
- var fd int
- var cpuWait uint64
-
- const clocksPerSec = 100
-
- c.AddCollect(func(ctx context.Context) {
- if gatheredFD, err := proc.FileDescriptorsLen(); err == nil {
- fd = gatheredFD
- }
-
- if gatheredIOStat, err := proc.IO(); err == nil {
- ioStat.SyscW = gatheredIOStat.SyscW
- ioStat.WriteBytes = gatheredIOStat.WriteBytes
- ioStat.SyscR = gatheredIOStat.SyscR
- ioStat.ReadBytes = gatheredIOStat.ReadBytes
- }
-
- if gatheredStat, err := proc.Stat(); err == nil {
- procStat.UTime = gatheredStat.UTime
- procStat.STime = gatheredStat.STime
- procStat.RSS = gatheredStat.RSS
- }
-
- if gatheredSched, err := proc.Schedstat(); err == nil {
- cpuWait = gatheredSched.WaitingNanoseconds
- }
- })
-
- procRegistry.FuncGauge("fd", c.RegisteredGauge(func() float64 {
- return float64(fd)
- }))
-
- ioRegistry := procRegistry.WithPrefix("io")
- ioRegistry.FuncCounter(r.ComposeName("read", "count"), c.RegisteredCounter(func() int64 {
- return int64(ioStat.SyscR)
- }))
- ioRegistry.FuncCounter(r.ComposeName("read", "bytes"), c.RegisteredCounter(func() int64 {
- return int64(ioStat.ReadBytes)
- }))
- ioRegistry.FuncCounter(r.ComposeName("write", "count"), c.RegisteredCounter(func() int64 {
- return int64(ioStat.SyscW)
- }))
- ioRegistry.FuncCounter(r.ComposeName("write", "bytes"), c.RegisteredCounter(func() int64 {
- return int64(ioStat.WriteBytes)
- }))
-
- cpuRegistry := procRegistry.WithPrefix("cpu")
- cpuRegistry.FuncCounter(r.ComposeName("total", "ns"), c.RegisteredCounter(func() int64 {
- return int64(procStat.UTime+procStat.STime) * (1_000_000_000 / clocksPerSec)
- }))
- cpuRegistry.FuncCounter(r.ComposeName("user", "ns"), c.RegisteredCounter(func() int64 {
- return int64(procStat.UTime) * (1_000_000_000 / clocksPerSec)
- }))
- cpuRegistry.FuncCounter(r.ComposeName("system", "ns"), c.RegisteredCounter(func() int64 {
- return int64(procStat.STime) * (1_000_000_000 / clocksPerSec)
- }))
- cpuRegistry.FuncCounter(r.ComposeName("wait", "ns"), c.RegisteredCounter(func() int64 {
- return int64(cpuWait)
- }))
-
- procRegistry.FuncGauge(r.ComposeName("mem", "rss"), c.RegisteredGauge(func() float64 {
- return float64(procStat.RSS)
- }))
-}
diff --git a/library/go/core/metrics/internal/pkg/metricsutil/buckets.go b/library/go/core/metrics/internal/pkg/metricsutil/buckets.go
deleted file mode 100644
index 5db605cd4d..0000000000
--- a/library/go/core/metrics/internal/pkg/metricsutil/buckets.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package metricsutil
-
-import (
- "sort"
-
- "a.yandex-team.ru/library/go/core/metrics"
-)
-
-// BucketsBounds unwraps Buckets bounds to slice of float64.
-func BucketsBounds(b metrics.Buckets) []float64 {
- bkts := make([]float64, b.Size())
- for i := range bkts {
- bkts[i] = b.UpperBound(i)
- }
- sort.Float64s(bkts)
- return bkts
-}
-
-// DurationBucketsBounds unwraps DurationBuckets bounds to slice of float64.
-func DurationBucketsBounds(b metrics.DurationBuckets) []float64 {
- bkts := make([]float64, b.Size())
- for i := range bkts {
- bkts[i] = b.UpperBound(i).Seconds()
- }
- sort.Float64s(bkts)
- return bkts
-}
diff --git a/library/go/core/metrics/internal/pkg/registryutil/registryutil.go b/library/go/core/metrics/internal/pkg/registryutil/registryutil.go
deleted file mode 100644
index ebce50d8cb..0000000000
--- a/library/go/core/metrics/internal/pkg/registryutil/registryutil.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package registryutil
-
-import (
- "errors"
- "fmt"
- "sort"
- "strconv"
- "strings"
-
- "github.com/OneOfOne/xxhash"
-)
-
-// BuildRegistryKey creates registry name based on given prefix and tags
-func BuildRegistryKey(prefix string, tags map[string]string) string {
- var builder strings.Builder
-
- builder.WriteString(strconv.Quote(prefix))
- builder.WriteRune('{')
- builder.WriteString(StringifyTags(tags))
- builder.WriteByte('}')
-
- return builder.String()
-}
-
-// BuildFQName returns name parts joined by given separator.
-// Mainly used to append prefix to registry
-func BuildFQName(separator string, parts ...string) (name string) {
- var b strings.Builder
- for _, p := range parts {
- if p == "" {
- continue
- }
- if b.Len() > 0 {
- b.WriteString(separator)
- }
- b.WriteString(strings.Trim(p, separator))
- }
- return b.String()
-}
-
-// MergeTags merges 2 sets of tags with the tags from tagsRight overriding values from tagsLeft
-func MergeTags(leftTags map[string]string, rightTags map[string]string) map[string]string {
- if leftTags == nil && rightTags == nil {
- return nil
- }
-
- if len(leftTags) == 0 {
- return rightTags
- }
-
- if len(rightTags) == 0 {
- return leftTags
- }
-
- newTags := make(map[string]string)
- for key, value := range leftTags {
- newTags[key] = value
- }
- for key, value := range rightTags {
- newTags[key] = value
- }
- return newTags
-}
-
-// StringifyTags returns string representation of given tags map.
-// It is guaranteed that equal sets of tags will produce equal strings.
-func StringifyTags(tags map[string]string) string {
- keys := make([]string, 0, len(tags))
- for key := range tags {
- keys = append(keys, key)
- }
- sort.Strings(keys)
-
- var builder strings.Builder
- for i, key := range keys {
- if i > 0 {
- builder.WriteByte(',')
- }
- builder.WriteString(key + "=" + tags[key])
- }
-
- return builder.String()
-}
-
-// VectorHash computes hash of metrics vector element
-func VectorHash(tags map[string]string, labels []string) (uint64, error) {
- if len(tags) != len(labels) {
- return 0, errors.New("inconsistent tags and labels sets")
- }
-
- h := xxhash.New64()
-
- for _, label := range labels {
- v, ok := tags[label]
- if !ok {
- return 0, fmt.Errorf("label '%s' not found in tags", label)
- }
- _, _ = h.WriteString(label)
- _, _ = h.WriteString(v)
- _, _ = h.WriteString(",")
- }
-
- return h.Sum64(), nil
-}
diff --git a/library/go/core/metrics/metrics.go b/library/go/core/metrics/metrics.go
deleted file mode 100644
index 0eb436046b..0000000000
--- a/library/go/core/metrics/metrics.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Package metrics provides interface collecting performance metrics.
-package metrics
-
-import (
- "context"
- "time"
-)
-
-// Gauge tracks single float64 value.
-type Gauge interface {
- Set(value float64)
- Add(value float64)
-}
-
-// FuncGauge is Gauge with value provided by callback function.
-type FuncGauge interface {
- Function() func() float64
-}
-
-// Counter tracks monotonically increasing value.
-type Counter interface {
- // Inc increments counter by 1.
- Inc()
-
- // Add adds delta to the counter. Delta must be >=0.
- Add(delta int64)
-}
-
-// FuncCounter is Counter with value provided by callback function.
-type FuncCounter interface {
- Function() func() int64
-}
-
-// Histogram tracks distribution of value.
-type Histogram interface {
- RecordValue(value float64)
-}
-
-// Timer measures durations.
-type Timer interface {
- RecordDuration(value time.Duration)
-}
-
-// DurationBuckets defines buckets of the duration histogram.
-type DurationBuckets interface {
- // Size returns number of buckets.
- Size() int
-
- // MapDuration returns index of the bucket.
- //
- // index is integer in range [0, Size()).
- MapDuration(d time.Duration) int
-
- // UpperBound of the last bucket is always +Inf.
- //
- // bucketIndex is integer in range [0, Size()-1).
- UpperBound(bucketIndex int) time.Duration
-}
-
-// Buckets defines intervals of the regular histogram.
-type Buckets interface {
- // Size returns number of buckets.
- Size() int
-
- // MapValue returns index of the bucket.
- //
- // Index is integer in range [0, Size()).
- MapValue(v float64) int
-
- // UpperBound of the last bucket is always +Inf.
- //
- // bucketIndex is integer in range [0, Size()-1).
- UpperBound(bucketIndex int) float64
-}
-
-// GaugeVec stores multiple dynamically created gauges.
-type GaugeVec interface {
- With(map[string]string) Gauge
-
- // Reset deletes all metrics in vector.
- Reset()
-}
-
-// CounterVec stores multiple dynamically created counters.
-type CounterVec interface {
- With(map[string]string) Counter
-
- // Reset deletes all metrics in vector.
- Reset()
-}
-
-// TimerVec stores multiple dynamically created timers.
-type TimerVec interface {
- With(map[string]string) Timer
-
- // Reset deletes all metrics in vector.
- Reset()
-}
-
-// HistogramVec stores multiple dynamically created histograms.
-type HistogramVec interface {
- With(map[string]string) Histogram
-
- // Reset deletes all metrics in vector.
- Reset()
-}
-
-// Registry creates profiling metrics.
-type Registry interface {
- // WithTags creates new sub-scope, where each metric has tags attached to it.
- WithTags(tags map[string]string) Registry
- // WithPrefix creates new sub-scope, where each metric has prefix added to it name.
- WithPrefix(prefix string) Registry
-
- ComposeName(parts ...string) string
-
- Counter(name string) Counter
- CounterVec(name string, labels []string) CounterVec
- FuncCounter(name string, function func() int64) FuncCounter
-
- Gauge(name string) Gauge
- GaugeVec(name string, labels []string) GaugeVec
- FuncGauge(name string, function func() float64) FuncGauge
-
- Timer(name string) Timer
- TimerVec(name string, labels []string) TimerVec
-
- Histogram(name string, buckets Buckets) Histogram
- HistogramVec(name string, buckets Buckets, labels []string) HistogramVec
-
- DurationHistogram(name string, buckets DurationBuckets) Timer
- DurationHistogramVec(name string, buckets DurationBuckets, labels []string) TimerVec
-}
-
-// CollectPolicy defines how registered gauge metrics are updated via collect func.
-type CollectPolicy interface {
- RegisteredCounter(counterFunc func() int64) func() int64
- RegisteredGauge(gaugeFunc func() float64) func() float64
- AddCollect(collect func(ctx context.Context))
-}
diff --git a/library/go/core/metrics/solomon/converter.go b/library/go/core/metrics/solomon/converter.go
deleted file mode 100644
index 4458d1a932..0000000000
--- a/library/go/core/metrics/solomon/converter.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package solomon
-
-import (
- "fmt"
-
- dto "github.com/prometheus/client_model/go"
- "go.uber.org/atomic"
-)
-
-// PrometheusMetrics converts Prometheus metrics to Solomon metrics.
-func PrometheusMetrics(metrics []*dto.MetricFamily) (*Metrics, error) {
- s := &Metrics{
- metrics: make([]Metric, 0, len(metrics)),
- }
-
- if len(metrics) == 0 {
- return s, nil
- }
-
- for _, mf := range metrics {
- if len(mf.Metric) == 0 {
- continue
- }
-
- metric := mf.Metric[0]
-
- tags := make(map[string]string, len(metric.Label))
- for _, label := range metric.Label {
- tags[label.GetName()] = label.GetValue()
- }
-
- switch *mf.Type {
- case dto.MetricType_COUNTER:
- s.metrics = append(s.metrics, &Counter{
- name: mf.GetName(),
- tags: tags,
- value: *atomic.NewInt64(int64(metric.Counter.GetValue())),
- })
- case dto.MetricType_GAUGE:
- s.metrics = append(s.metrics, &Gauge{
- name: mf.GetName(),
- tags: tags,
- value: *atomic.NewFloat64(metric.Gauge.GetValue()),
- })
- case dto.MetricType_HISTOGRAM:
- bounds := make([]float64, 0, len(metric.Histogram.Bucket))
- values := make([]int64, 0, len(metric.Histogram.Bucket))
-
- var prevValuesSum int64
-
- for _, bucket := range metric.Histogram.Bucket {
- // prometheus uses cumulative buckets where solomon uses instant
- bucketValue := int64(bucket.GetCumulativeCount())
- bucketValue -= prevValuesSum
- prevValuesSum += bucketValue
-
- bounds = append(bounds, bucket.GetUpperBound())
- values = append(values, bucketValue)
- }
-
- s.metrics = append(s.metrics, &Histogram{
- name: mf.GetName(),
- tags: tags,
- bucketBounds: bounds,
- bucketValues: values,
- })
- default:
- return nil, fmt.Errorf("unsupported type: %s", mf.Type.String())
- }
- }
-
- return s, nil
-}
diff --git a/library/go/core/metrics/solomon/counter.go b/library/go/core/metrics/solomon/counter.go
deleted file mode 100644
index 64ea1b47ca..0000000000
--- a/library/go/core/metrics/solomon/counter.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package solomon
-
-import (
- "encoding/json"
- "time"
-
- "go.uber.org/atomic"
-
- "a.yandex-team.ru/library/go/core/metrics"
-)
-
-var (
- _ metrics.Counter = (*Counter)(nil)
- _ Metric = (*Counter)(nil)
-)
-
-// Counter tracks monotonically increasing value.
-type Counter struct {
- name string
- metricType metricType
- tags map[string]string
- value atomic.Int64
- timestamp *time.Time
-
- useNameTag bool
-}
-
-// Inc increments counter by 1.
-func (c *Counter) Inc() {
- c.Add(1)
-}
-
-// Add adds delta to the counter. Delta must be >=0.
-func (c *Counter) Add(delta int64) {
- c.value.Add(delta)
-}
-
-func (c *Counter) Name() string {
- return c.name
-}
-
-func (c *Counter) getType() metricType {
- return c.metricType
-}
-
-func (c *Counter) getLabels() map[string]string {
- return c.tags
-}
-
-func (c *Counter) getValue() interface{} {
- return c.value.Load()
-}
-
-func (c *Counter) getTimestamp() *time.Time {
- return c.timestamp
-}
-
-func (c *Counter) getNameTag() string {
- if c.useNameTag {
- return "name"
- } else {
- return "sensor"
- }
-}
-
-// MarshalJSON implements json.Marshaler.
-func (c *Counter) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string `json:"type"`
- Labels map[string]string `json:"labels"`
- Value int64 `json:"value"`
- Timestamp *int64 `json:"ts,omitempty"`
- }{
- Type: c.metricType.String(),
- Value: c.value.Load(),
- Labels: func() map[string]string {
- labels := make(map[string]string, len(c.tags)+1)
- labels[c.getNameTag()] = c.Name()
- for k, v := range c.tags {
- labels[k] = v
- }
- return labels
- }(),
- Timestamp: tsAsRef(c.timestamp),
- })
-}
-
-// Snapshot returns independent copy on metric.
-func (c *Counter) Snapshot() Metric {
- return &Counter{
- name: c.name,
- metricType: c.metricType,
- tags: c.tags,
- value: *atomic.NewInt64(c.value.Load()),
-
- useNameTag: c.useNameTag,
- }
-}
diff --git a/library/go/core/metrics/solomon/func_counter.go b/library/go/core/metrics/solomon/func_counter.go
deleted file mode 100644
index db862869e4..0000000000
--- a/library/go/core/metrics/solomon/func_counter.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package solomon
-
-import (
- "encoding/json"
- "time"
-
- "go.uber.org/atomic"
-)
-
-var _ Metric = (*FuncCounter)(nil)
-
-// FuncCounter tracks int64 value returned by function.
-type FuncCounter struct {
- name string
- metricType metricType
- tags map[string]string
- function func() int64
- timestamp *time.Time
- useNameTag bool
-}
-
-func (c *FuncCounter) Name() string {
- return c.name
-}
-
-func (c *FuncCounter) Function() func() int64 {
- return c.function
-}
-
-func (c *FuncCounter) getType() metricType {
- return c.metricType
-}
-
-func (c *FuncCounter) getLabels() map[string]string {
- return c.tags
-}
-
-func (c *FuncCounter) getValue() interface{} {
- return c.function()
-}
-
-func (c *FuncCounter) getTimestamp() *time.Time {
- return c.timestamp
-}
-
-func (c *FuncCounter) getNameTag() string {
- if c.useNameTag {
- return "name"
- } else {
- return "sensor"
- }
-}
-
-// MarshalJSON implements json.Marshaler.
-func (c *FuncCounter) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string `json:"type"`
- Labels map[string]string `json:"labels"`
- Value int64 `json:"value"`
- Timestamp *int64 `json:"ts,omitempty"`
- }{
- Type: c.metricType.String(),
- Value: c.function(),
- Labels: func() map[string]string {
- labels := make(map[string]string, len(c.tags)+1)
- labels[c.getNameTag()] = c.Name()
- for k, v := range c.tags {
- labels[k] = v
- }
- return labels
- }(),
- Timestamp: tsAsRef(c.timestamp),
- })
-}
-
-// Snapshot returns independent copy on metric.
-func (c *FuncCounter) Snapshot() Metric {
- return &Counter{
- name: c.name,
- metricType: c.metricType,
- tags: c.tags,
- value: *atomic.NewInt64(c.function()),
-
- useNameTag: c.useNameTag,
- }
-}
diff --git a/library/go/core/metrics/solomon/func_gauge.go b/library/go/core/metrics/solomon/func_gauge.go
deleted file mode 100644
index ce824c6fa8..0000000000
--- a/library/go/core/metrics/solomon/func_gauge.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package solomon
-
-import (
- "encoding/json"
- "time"
-
- "go.uber.org/atomic"
-)
-
-var _ Metric = (*FuncGauge)(nil)
-
-// FuncGauge tracks float64 value returned by function.
-type FuncGauge struct {
- name string
- metricType metricType
- tags map[string]string
- function func() float64
- timestamp *time.Time
-
- useNameTag bool
-}
-
-func (g *FuncGauge) Name() string {
- return g.name
-}
-
-func (g *FuncGauge) Function() func() float64 {
- return g.function
-}
-
-func (g *FuncGauge) getType() metricType {
- return g.metricType
-}
-
-func (g *FuncGauge) getLabels() map[string]string {
- return g.tags
-}
-
-func (g *FuncGauge) getValue() interface{} {
- return g.function()
-}
-
-func (g *FuncGauge) getTimestamp() *time.Time {
- return g.timestamp
-}
-
-func (g *FuncGauge) getNameTag() string {
- if g.useNameTag {
- return "name"
- } else {
- return "sensor"
- }
-}
-
-// MarshalJSON implements json.Marshaler.
-func (g *FuncGauge) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string `json:"type"`
- Labels map[string]string `json:"labels"`
- Value float64 `json:"value"`
- Timestamp *int64 `json:"ts,omitempty"`
- }{
- Type: g.metricType.String(),
- Value: g.function(),
- Labels: func() map[string]string {
- labels := make(map[string]string, len(g.tags)+1)
- labels[g.getNameTag()] = g.Name()
- for k, v := range g.tags {
- labels[k] = v
- }
- return labels
- }(),
- Timestamp: tsAsRef(g.timestamp),
- })
-}
-
-// Snapshot returns independent copy on metric.
-func (g *FuncGauge) Snapshot() Metric {
- return &Gauge{
- name: g.name,
- metricType: g.metricType,
- tags: g.tags,
- value: *atomic.NewFloat64(g.function()),
-
- useNameTag: g.useNameTag,
- }
-}
diff --git a/library/go/core/metrics/solomon/gauge.go b/library/go/core/metrics/solomon/gauge.go
deleted file mode 100644
index 4d7e17195d..0000000000
--- a/library/go/core/metrics/solomon/gauge.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package solomon
-
-import (
- "encoding/json"
- "time"
-
- "go.uber.org/atomic"
-
- "a.yandex-team.ru/library/go/core/metrics"
-)
-
-var (
- _ metrics.Gauge = (*Gauge)(nil)
- _ Metric = (*Gauge)(nil)
-)
-
-// Gauge tracks single float64 value.
-type Gauge struct {
- name string
- metricType metricType
- tags map[string]string
- value atomic.Float64
- timestamp *time.Time
-
- useNameTag bool
-}
-
-func NewGauge(name string, value float64, opts ...metricOpts) Gauge {
- mOpts := MetricsOpts{}
- for _, op := range opts {
- op(&mOpts)
- }
- return Gauge{
- name: name,
- metricType: typeGauge,
- tags: mOpts.tags,
- value: *atomic.NewFloat64(value),
- useNameTag: mOpts.useNameTag,
- timestamp: mOpts.timestamp,
- }
-}
-
-func (g *Gauge) Set(value float64) {
- g.value.Store(value)
-}
-
-func (g *Gauge) Add(value float64) {
- g.value.Add(value)
-}
-
-func (g *Gauge) Name() string {
- return g.name
-}
-
-func (g *Gauge) getType() metricType {
- return g.metricType
-}
-
-func (g *Gauge) getLabels() map[string]string {
- return g.tags
-}
-
-func (g *Gauge) getValue() interface{} {
- return g.value.Load()
-}
-
-func (g *Gauge) getTimestamp() *time.Time {
- return g.timestamp
-}
-
-func (g *Gauge) getNameTag() string {
- if g.useNameTag {
- return "name"
- } else {
- return "sensor"
- }
-}
-
-// MarshalJSON implements json.Marshaler.
-func (g *Gauge) MarshalJSON() ([]byte, error) {
- metricType := g.metricType.String()
- value := g.value.Load()
- labels := func() map[string]string {
- labels := make(map[string]string, len(g.tags)+1)
- labels[g.getNameTag()] = g.Name()
- for k, v := range g.tags {
- labels[k] = v
- }
- return labels
- }()
-
- return json.Marshal(struct {
- Type string `json:"type"`
- Labels map[string]string `json:"labels"`
- Value float64 `json:"value"`
- Timestamp *int64 `json:"ts,omitempty"`
- }{
- Type: metricType,
- Value: value,
- Labels: labels,
- Timestamp: tsAsRef(g.timestamp),
- })
-}
-
-// Snapshot returns independent copy of metric.
-func (g *Gauge) Snapshot() Metric {
- return &Gauge{
- name: g.name,
- metricType: g.metricType,
- tags: g.tags,
- value: *atomic.NewFloat64(g.value.Load()),
-
- useNameTag: g.useNameTag,
- timestamp: g.timestamp,
- }
-}
diff --git a/library/go/core/metrics/solomon/histogram.go b/library/go/core/metrics/solomon/histogram.go
deleted file mode 100644
index 574aeaccf6..0000000000
--- a/library/go/core/metrics/solomon/histogram.go
+++ /dev/null
@@ -1,177 +0,0 @@
-package solomon
-
-import (
- "encoding/binary"
- "encoding/json"
- "io"
- "sort"
- "sync"
- "time"
-
- "go.uber.org/atomic"
-
- "a.yandex-team.ru/library/go/core/metrics"
- "a.yandex-team.ru/library/go/core/xerrors"
-)
-
-var (
- _ metrics.Histogram = (*Histogram)(nil)
- _ metrics.Timer = (*Histogram)(nil)
- _ Metric = (*Histogram)(nil)
-)
-
-type Histogram struct {
- name string
- metricType metricType
- tags map[string]string
- bucketBounds []float64
- bucketValues []int64
- infValue atomic.Int64
- mutex sync.Mutex
- timestamp *time.Time
- useNameTag bool
-}
-
-type histogram struct {
- Bounds []float64 `json:"bounds"`
- Buckets []int64 `json:"buckets"`
- Inf int64 `json:"inf,omitempty"`
-}
-
-func (h *histogram) writeHistogram(w io.Writer) error {
- err := writeULEB128(w, uint32(len(h.Buckets)))
- if err != nil {
- return xerrors.Errorf("writeULEB128 size histogram buckets failed: %w", err)
- }
-
- for _, upperBound := range h.Bounds {
- err = binary.Write(w, binary.LittleEndian, float64(upperBound))
- if err != nil {
- return xerrors.Errorf("binary.Write upper bound failed: %w", err)
- }
- }
-
- for _, bucketValue := range h.Buckets {
- err = binary.Write(w, binary.LittleEndian, uint64(bucketValue))
- if err != nil {
- return xerrors.Errorf("binary.Write histogram buckets failed: %w", err)
- }
- }
- return nil
-}
-
-func (h *Histogram) RecordValue(value float64) {
- boundIndex := sort.SearchFloat64s(h.bucketBounds, value)
-
- if boundIndex < len(h.bucketValues) {
- h.mutex.Lock()
- h.bucketValues[boundIndex] += 1
- h.mutex.Unlock()
- } else {
- h.infValue.Inc()
- }
-}
-
-func (h *Histogram) RecordDuration(value time.Duration) {
- h.RecordValue(value.Seconds())
-}
-
-func (h *Histogram) Reset() {
- h.mutex.Lock()
- defer h.mutex.Unlock()
-
- h.bucketValues = make([]int64, len(h.bucketValues))
- h.infValue.Store(0)
-}
-
-func (h *Histogram) Name() string {
- return h.name
-}
-
-func (h *Histogram) getType() metricType {
- return h.metricType
-}
-
-func (h *Histogram) getLabels() map[string]string {
- return h.tags
-}
-
-func (h *Histogram) getValue() interface{} {
- return histogram{
- Bounds: h.bucketBounds,
- Buckets: h.bucketValues,
- }
-}
-
-func (h *Histogram) getTimestamp() *time.Time {
- return h.timestamp
-}
-
-func (h *Histogram) getNameTag() string {
- if h.useNameTag {
- return "name"
- } else {
- return "sensor"
- }
-}
-
-// MarshalJSON implements json.Marshaler.
-func (h *Histogram) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string `json:"type"`
- Labels map[string]string `json:"labels"`
- Histogram histogram `json:"hist"`
- Timestamp *int64 `json:"ts,omitempty"`
- }{
- Type: h.metricType.String(),
- Histogram: histogram{
- Bounds: h.bucketBounds,
- Buckets: h.bucketValues,
- Inf: h.infValue.Load(),
- },
- Labels: func() map[string]string {
- labels := make(map[string]string, len(h.tags)+1)
- labels[h.getNameTag()] = h.Name()
- for k, v := range h.tags {
- labels[k] = v
- }
- return labels
- }(),
- Timestamp: tsAsRef(h.timestamp),
- })
-}
-
-// Snapshot returns independent copy on metric.
-func (h *Histogram) Snapshot() Metric {
- bucketBounds := make([]float64, len(h.bucketBounds))
- bucketValues := make([]int64, len(h.bucketValues))
-
- copy(bucketBounds, h.bucketBounds)
- copy(bucketValues, h.bucketValues)
-
- return &Histogram{
- name: h.name,
- metricType: h.metricType,
- tags: h.tags,
- bucketBounds: bucketBounds,
- bucketValues: bucketValues,
- infValue: *atomic.NewInt64(h.infValue.Load()),
- useNameTag: h.useNameTag,
- }
-}
-
-// InitBucketValues cleans internal bucketValues and saves new values in order.
-// Length of internal bucketValues stays unchanged.
-// If length of slice in argument bucketValues more than length of internal one,
-// the first extra element of bucketValues is stored in infValue.
-func (h *Histogram) InitBucketValues(bucketValues []int64) {
- h.mutex.Lock()
- defer h.mutex.Unlock()
-
- h.bucketValues = make([]int64, len(h.bucketValues))
- h.infValue.Store(0)
- copy(h.bucketValues, bucketValues)
- if len(bucketValues) > len(h.bucketValues) {
- h.infValue.Store(bucketValues[len(h.bucketValues)])
- }
-}
diff --git a/library/go/core/metrics/solomon/metrics.go b/library/go/core/metrics/solomon/metrics.go
deleted file mode 100644
index 7f4bf4b5ec..0000000000
--- a/library/go/core/metrics/solomon/metrics.go
+++ /dev/null
@@ -1,178 +0,0 @@
-package solomon
-
-import (
- "bytes"
- "context"
- "encoding"
- "encoding/json"
- "fmt"
- "time"
-
- "a.yandex-team.ru/library/go/core/xerrors"
-)
-
-// Gather collects all metrics data via snapshots.
-func (r Registry) Gather() (*Metrics, error) {
- metrics := make([]Metric, 0)
-
- var err error
- r.metrics.Range(func(_, v interface{}) bool {
- if s, ok := v.(Metric); ok {
- metrics = append(metrics, s.Snapshot())
- return true
- }
- err = fmt.Errorf("unexpected value type: %T", v)
- return false
- })
-
- if err != nil {
- return nil, err
- }
-
- return &Metrics{metrics: metrics}, nil
-}
-
-func NewMetrics(metrics []Metric) Metrics {
- return Metrics{metrics: metrics}
-}
-
-func NewMetricsWithTimestamp(metrics []Metric, ts time.Time) Metrics {
- return Metrics{metrics: metrics, timestamp: &ts}
-}
-
-type valueType uint8
-
-const (
- valueTypeNone valueType = iota
- valueTypeOneWithoutTS valueType = 0x01
- valueTypeOneWithTS valueType = 0x02
- valueTypeManyWithTS valueType = 0x03
-)
-
-type metricType uint8
-
-const (
- typeUnspecified metricType = iota
- typeGauge metricType = 0x01
- typeCounter metricType = 0x02
- typeRated metricType = 0x03
- typeHistogram metricType = 0x05
- typeRatedHistogram metricType = 0x06
-)
-
-func (k metricType) String() string {
- switch k {
- case typeCounter:
- return "COUNTER"
- case typeGauge:
- return "DGAUGE"
- case typeHistogram:
- return "HIST"
- case typeRated:
- return "RATE"
- case typeRatedHistogram:
- return "HIST_RATE"
- default:
- panic("unknown metric type")
- }
-}
-
-// Metric is an any abstract solomon Metric.
-type Metric interface {
- json.Marshaler
-
- Name() string
- getType() metricType
- getLabels() map[string]string
- getValue() interface{}
- getNameTag() string
- getTimestamp() *time.Time
-
- Snapshot() Metric
-}
-
-// Rated marks given Solomon metric or vector as rated.
-// Example:
-//
-// cnt := r.Counter("mycounter")
-// Rated(cnt)
-//
-// cntvec := r.CounterVec("mycounter", []string{"mytag"})
-// Rated(cntvec)
-//
-// For additional info: https://docs.yandex-team.ru/solomon/data-collection/dataformat/json
-func Rated(s interface{}) {
- switch st := s.(type) {
- case *Counter:
- st.metricType = typeRated
- case *FuncCounter:
- st.metricType = typeRated
- case *Histogram:
- st.metricType = typeRatedHistogram
-
- case *CounterVec:
- st.vec.rated = true
- case *HistogramVec:
- st.vec.rated = true
- case *DurationHistogramVec:
- st.vec.rated = true
- }
- // any other metrics types are unrateable
-}
-
-var (
- _ json.Marshaler = (*Metrics)(nil)
- _ encoding.BinaryMarshaler = (*Metrics)(nil)
-)
-
-type Metrics struct {
- metrics []Metric
- timestamp *time.Time
-}
-
-// MarshalJSON implements json.Marshaler.
-func (s Metrics) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Metrics []Metric `json:"metrics"`
- Timestamp *int64 `json:"ts,omitempty"`
- }{s.metrics, tsAsRef(s.timestamp)})
-}
-
-// MarshalBinary implements encoding.BinaryMarshaler.
-func (s Metrics) MarshalBinary() ([]byte, error) {
- var buf bytes.Buffer
- se := NewSpackEncoder(context.Background(), CompressionNone, &s)
- n, err := se.Encode(&buf)
- if err != nil {
- return nil, xerrors.Errorf("encode only %d bytes: %w", n, err)
- }
- return buf.Bytes(), nil
-}
-
-// SplitToChunks splits Metrics into a slice of chunks, each at most maxChunkSize long.
-// The length of returned slice is always at least one.
-// Zero maxChunkSize denotes unlimited chunk length.
-func (s Metrics) SplitToChunks(maxChunkSize int) []Metrics {
- if maxChunkSize == 0 || len(s.metrics) == 0 {
- return []Metrics{s}
- }
- chunks := make([]Metrics, 0, len(s.metrics)/maxChunkSize+1)
-
- for leftBound := 0; leftBound < len(s.metrics); leftBound += maxChunkSize {
- rightBound := leftBound + maxChunkSize
- if rightBound > len(s.metrics) {
- rightBound = len(s.metrics)
- }
- chunk := s.metrics[leftBound:rightBound]
- chunks = append(chunks, Metrics{metrics: chunk})
- }
- return chunks
-}
-
-func tsAsRef(t *time.Time) *int64 {
- if t == nil {
- return nil
- }
- ts := t.Unix()
- return &ts
-}
diff --git a/library/go/core/metrics/solomon/metrics_opts.go b/library/go/core/metrics/solomon/metrics_opts.go
deleted file mode 100644
index d9ade67966..0000000000
--- a/library/go/core/metrics/solomon/metrics_opts.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package solomon
-
-import "time"
-
-type MetricsOpts struct {
- useNameTag bool
- tags map[string]string
- timestamp *time.Time
-}
-
-type metricOpts func(*MetricsOpts)
-
-func WithTags(tags map[string]string) func(*MetricsOpts) {
- return func(m *MetricsOpts) {
- m.tags = tags
- }
-}
-
-func WithUseNameTag() func(*MetricsOpts) {
- return func(m *MetricsOpts) {
- m.useNameTag = true
- }
-}
-
-func WithTimestamp(t time.Time) func(*MetricsOpts) {
- return func(m *MetricsOpts) {
- m.timestamp = &t
- }
-}
diff --git a/library/go/core/metrics/solomon/registry.go b/library/go/core/metrics/solomon/registry.go
deleted file mode 100644
index cdd7489843..0000000000
--- a/library/go/core/metrics/solomon/registry.go
+++ /dev/null
@@ -1,221 +0,0 @@
-package solomon
-
-import (
- "reflect"
- "strconv"
- "sync"
-
- "a.yandex-team.ru/library/go/core/metrics"
- "a.yandex-team.ru/library/go/core/metrics/internal/pkg/metricsutil"
- "a.yandex-team.ru/library/go/core/metrics/internal/pkg/registryutil"
-)
-
-var _ metrics.Registry = (*Registry)(nil)
-
-type Registry struct {
- separator string
- prefix string
- tags map[string]string
- rated bool
- useNameTag bool
-
- subregistries map[string]*Registry
- m *sync.Mutex
-
- metrics *sync.Map
-}
-
-func NewRegistry(opts *RegistryOpts) *Registry {
- r := &Registry{
- separator: ".",
- useNameTag: false,
-
- subregistries: make(map[string]*Registry),
- m: new(sync.Mutex),
-
- metrics: new(sync.Map),
- }
-
- if opts != nil {
- r.separator = string(opts.Separator)
- r.prefix = opts.Prefix
- r.tags = opts.Tags
- r.rated = opts.Rated
- r.useNameTag = opts.UseNameTag
- for _, collector := range opts.Collectors {
- collector(r)
- }
- }
-
- return r
-}
-
-// Rated returns copy of registry with rated set to desired value.
-func (r Registry) Rated(rated bool) metrics.Registry {
- return &Registry{
- separator: r.separator,
- prefix: r.prefix,
- tags: r.tags,
- rated: rated,
- useNameTag: r.useNameTag,
-
- subregistries: r.subregistries,
- m: r.m,
-
- metrics: r.metrics,
- }
-}
-
-// WithTags creates new sub-scope, where each metric has tags attached to it.
-func (r Registry) WithTags(tags map[string]string) metrics.Registry {
- return r.newSubregistry(r.prefix, registryutil.MergeTags(r.tags, tags))
-}
-
-// WithPrefix creates new sub-scope, where each metric has prefix added to it name.
-func (r Registry) WithPrefix(prefix string) metrics.Registry {
- return r.newSubregistry(registryutil.BuildFQName(r.separator, r.prefix, prefix), r.tags)
-}
-
-// ComposeName builds FQ name with appropriate separator.
-func (r Registry) ComposeName(parts ...string) string {
- return registryutil.BuildFQName(r.separator, parts...)
-}
-
-func (r Registry) Counter(name string) metrics.Counter {
- s := &Counter{
- name: r.newMetricName(name),
- metricType: typeCounter,
- tags: r.tags,
-
- useNameTag: r.useNameTag,
- }
-
- return r.registerMetric(s).(metrics.Counter)
-}
-
-func (r Registry) FuncCounter(name string, function func() int64) metrics.FuncCounter {
- s := &FuncCounter{
- name: r.newMetricName(name),
- metricType: typeCounter,
- tags: r.tags,
- function: function,
- useNameTag: r.useNameTag,
- }
-
- return r.registerMetric(s).(metrics.FuncCounter)
-}
-
-func (r Registry) Gauge(name string) metrics.Gauge {
- s := &Gauge{
- name: r.newMetricName(name),
- metricType: typeGauge,
- tags: r.tags,
- useNameTag: r.useNameTag,
- }
-
- return r.registerMetric(s).(metrics.Gauge)
-}
-
-func (r Registry) FuncGauge(name string, function func() float64) metrics.FuncGauge {
- s := &FuncGauge{
- name: r.newMetricName(name),
- metricType: typeGauge,
- tags: r.tags,
- function: function,
- useNameTag: r.useNameTag,
- }
-
- return r.registerMetric(s).(metrics.FuncGauge)
-}
-
-func (r Registry) Timer(name string) metrics.Timer {
- s := &Timer{
- name: r.newMetricName(name),
- metricType: typeGauge,
- tags: r.tags,
- useNameTag: r.useNameTag,
- }
-
- return r.registerMetric(s).(metrics.Timer)
-}
-
-func (r Registry) Histogram(name string, buckets metrics.Buckets) metrics.Histogram {
- s := &Histogram{
- name: r.newMetricName(name),
- metricType: typeHistogram,
- tags: r.tags,
- bucketBounds: metricsutil.BucketsBounds(buckets),
- bucketValues: make([]int64, buckets.Size()),
- useNameTag: r.useNameTag,
- }
-
- return r.registerMetric(s).(metrics.Histogram)
-}
-
-func (r Registry) DurationHistogram(name string, buckets metrics.DurationBuckets) metrics.Timer {
- s := &Histogram{
- name: r.newMetricName(name),
- metricType: typeHistogram,
- tags: r.tags,
- bucketBounds: metricsutil.DurationBucketsBounds(buckets),
- bucketValues: make([]int64, buckets.Size()),
- useNameTag: r.useNameTag,
- }
-
- return r.registerMetric(s).(metrics.Timer)
-}
-
-func (r *Registry) newSubregistry(prefix string, tags map[string]string) *Registry {
- // differ simple and rated registries
- keyTags := registryutil.MergeTags(tags, map[string]string{"rated": strconv.FormatBool(r.rated)})
- registryKey := registryutil.BuildRegistryKey(prefix, keyTags)
-
- r.m.Lock()
- defer r.m.Unlock()
-
- if existing, ok := r.subregistries[registryKey]; ok {
- return existing
- }
-
- subregistry := &Registry{
- separator: r.separator,
- prefix: prefix,
- tags: tags,
- rated: r.rated,
- useNameTag: r.useNameTag,
-
- subregistries: r.subregistries,
- m: r.m,
-
- metrics: r.metrics,
- }
-
- r.subregistries[registryKey] = subregistry
- return subregistry
-}
-
-func (r *Registry) newMetricName(name string) string {
- return registryutil.BuildFQName(r.separator, r.prefix, name)
-}
-
-func (r *Registry) registerMetric(s Metric) Metric {
- if r.rated {
- Rated(s)
- }
-
- // differ simple and rated registries
- keyTags := registryutil.MergeTags(r.tags, map[string]string{"rated": strconv.FormatBool(r.rated)})
- key := registryutil.BuildRegistryKey(s.Name(), keyTags)
-
- oldMetric, loaded := r.metrics.LoadOrStore(key, s)
- if !loaded {
- return s
- }
-
- if reflect.TypeOf(oldMetric) == reflect.TypeOf(s) {
- return oldMetric.(Metric)
- } else {
- r.metrics.Store(key, s)
- return s
- }
-}
diff --git a/library/go/core/metrics/solomon/registry_opts.go b/library/go/core/metrics/solomon/registry_opts.go
deleted file mode 100644
index d2d19718ee..0000000000
--- a/library/go/core/metrics/solomon/registry_opts.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package solomon
-
-import (
- "context"
-
- "a.yandex-team.ru/library/go/core/metrics"
- "a.yandex-team.ru/library/go/core/metrics/collect"
- "a.yandex-team.ru/library/go/core/metrics/internal/pkg/registryutil"
-)
-
-type RegistryOpts struct {
- Separator rune
- Prefix string
- Tags map[string]string
- Rated bool
- UseNameTag bool
- Collectors []func(metrics.Registry)
-}
-
-// NewRegistryOpts returns new initialized instance of RegistryOpts
-func NewRegistryOpts() *RegistryOpts {
- return &RegistryOpts{
- Separator: '.',
- Tags: make(map[string]string),
- UseNameTag: false,
- }
-}
-
-// SetUseNameTag overrides current UseNameTag opt
-func (o *RegistryOpts) SetUseNameTag(useNameTag bool) *RegistryOpts {
- o.UseNameTag = useNameTag
- return o
-}
-
-// SetTags overrides existing tags
-func (o *RegistryOpts) SetTags(tags map[string]string) *RegistryOpts {
- o.Tags = tags
- return o
-}
-
-// AddTags merges given tags with existing
-func (o *RegistryOpts) AddTags(tags map[string]string) *RegistryOpts {
- for k, v := range tags {
- o.Tags[k] = v
- }
- return o
-}
-
-// SetPrefix overrides existing prefix
-func (o *RegistryOpts) SetPrefix(prefix string) *RegistryOpts {
- o.Prefix = prefix
- return o
-}
-
-// AppendPrefix adds given prefix as postfix to existing using separator
-func (o *RegistryOpts) AppendPrefix(prefix string) *RegistryOpts {
- o.Prefix = registryutil.BuildFQName(string(o.Separator), o.Prefix, prefix)
- return o
-}
-
-// SetSeparator overrides existing separator
-func (o *RegistryOpts) SetSeparator(separator rune) *RegistryOpts {
- o.Separator = separator
- return o
-}
-
-// SetRated overrides existing rated flag
-func (o *RegistryOpts) SetRated(rated bool) *RegistryOpts {
- o.Rated = rated
- return o
-}
-
-// AddCollectors adds collectors that handle their metrics automatically (e.g. system metrics).
-func (o *RegistryOpts) AddCollectors(
- ctx context.Context, c metrics.CollectPolicy, collectors ...collect.Func,
-) *RegistryOpts {
- if len(collectors) == 0 {
- return o
- }
-
- o.Collectors = append(o.Collectors, func(r metrics.Registry) {
- for _, collector := range collectors {
- collector(ctx, r, c)
- }
- })
- return o
-}
diff --git a/library/go/core/metrics/solomon/spack.go b/library/go/core/metrics/solomon/spack.go
deleted file mode 100644
index 9dc0434716..0000000000
--- a/library/go/core/metrics/solomon/spack.go
+++ /dev/null
@@ -1,340 +0,0 @@
-package solomon
-
-import (
- "bytes"
- "context"
- "encoding/binary"
- "io"
-
- "a.yandex-team.ru/library/go/core/xerrors"
-)
-
-type errWriter struct {
- w io.Writer
- err error
-}
-
-func (ew *errWriter) binaryWrite(data interface{}) {
- if ew.err != nil {
- return
- }
- switch t := data.(type) {
- case uint8:
- ew.err = binary.Write(ew.w, binary.LittleEndian, data.(uint8))
- case uint16:
- ew.err = binary.Write(ew.w, binary.LittleEndian, data.(uint16))
- case uint32:
- ew.err = binary.Write(ew.w, binary.LittleEndian, data.(uint32))
- default:
- ew.err = xerrors.Errorf("binaryWrite not supported type %v", t)
- }
-}
-
-func writeULEB128(w io.Writer, value uint32) error {
- remaining := value >> 7
- for remaining != 0 {
- err := binary.Write(w, binary.LittleEndian, uint8(value&0x7f|0x80))
- if err != nil {
- return xerrors.Errorf("binary.Write failed: %w", err)
- }
- value = remaining
- remaining >>= 7
- }
- err := binary.Write(w, binary.LittleEndian, uint8(value&0x7f))
- if err != nil {
- return xerrors.Errorf("binary.Write failed: %w", err)
- }
- return err
-}
-
-type spackMetric struct {
- flags uint8
-
- labelsCount uint32
- labels bytes.Buffer
-
- metric Metric
-}
-
-func (s *spackMetric) writeLabel(se *spackEncoder, namesIdx map[string]uint32, valuesIdx map[string]uint32, name string, value string) error {
- s.labelsCount++
-
- _, ok := namesIdx[name]
- if !ok {
- namesIdx[name] = se.nameCounter
- se.nameCounter++
- _, err := se.labelNamePool.WriteString(name)
- if err != nil {
- return err
- }
- err = se.labelNamePool.WriteByte(0)
- if err != nil {
- return err
- }
- }
-
- _, ok = valuesIdx[value]
- if !ok {
- valuesIdx[value] = se.valueCounter
- se.valueCounter++
- _, err := se.labelValuePool.WriteString(value)
- if err != nil {
- return err
- }
- err = se.labelValuePool.WriteByte(0)
- if err != nil {
- return err
- }
- }
-
- err := writeULEB128(&s.labels, uint32(namesIdx[name]))
- if err != nil {
- return err
- }
- err = writeULEB128(&s.labels, uint32(valuesIdx[value]))
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (s *spackMetric) writeMetric(w io.Writer) error {
- metricValueType := valueTypeOneWithoutTS
- if s.metric.getTimestamp() != nil {
- metricValueType = valueTypeOneWithTS
- }
- // library/cpp/monlib/encode/spack/spack_v1_encoder.cpp?rev=r9098142#L190
- types := uint8(s.metric.getType()<<2) | uint8(metricValueType)
- err := binary.Write(w, binary.LittleEndian, types)
- if err != nil {
- return xerrors.Errorf("binary.Write types failed: %w", err)
- }
-
- err = binary.Write(w, binary.LittleEndian, uint8(s.flags))
- if err != nil {
- return xerrors.Errorf("binary.Write flags failed: %w", err)
- }
-
- err = writeULEB128(w, uint32(s.labelsCount))
- if err != nil {
- return xerrors.Errorf("writeULEB128 labels count failed: %w", err)
- }
-
- _, err = w.Write(s.labels.Bytes()) // s.writeLabels(w)
- if err != nil {
- return xerrors.Errorf("write labels failed: %w", err)
- }
- if s.metric.getTimestamp() != nil {
- err = binary.Write(w, binary.LittleEndian, uint32(s.metric.getTimestamp().Unix()))
- if err != nil {
- return xerrors.Errorf("write timestamp failed: %w", err)
- }
- }
-
- switch s.metric.getType() {
- case typeGauge:
- err = binary.Write(w, binary.LittleEndian, s.metric.getValue().(float64))
- if err != nil {
- return xerrors.Errorf("binary.Write gauge value failed: %w", err)
- }
- case typeCounter, typeRated:
- err = binary.Write(w, binary.LittleEndian, uint64(s.metric.getValue().(int64)))
- if err != nil {
- return xerrors.Errorf("binary.Write counter value failed: %w", err)
- }
- case typeHistogram, typeRatedHistogram:
- h := s.metric.getValue().(histogram)
- err = h.writeHistogram(w)
- if err != nil {
- return xerrors.Errorf("writeHistogram failed: %w", err)
- }
- default:
- return xerrors.Errorf("unknown metric type: %v", s.metric.getType())
- }
- return nil
-}
-
-type spackEncoder struct {
- context context.Context
- compression uint8
-
- nameCounter uint32
- valueCounter uint32
-
- labelNamePool bytes.Buffer
- labelValuePool bytes.Buffer
-
- metrics Metrics
-}
-
-func NewSpackEncoder(ctx context.Context, compression CompressionType, metrics *Metrics) *spackEncoder {
- if metrics == nil {
- metrics = &Metrics{}
- }
- return &spackEncoder{
- context: ctx,
- compression: uint8(compression),
- metrics: *metrics,
- }
-}
-
-func (se *spackEncoder) writeLabels() ([]spackMetric, error) {
- namesIdx := make(map[string]uint32)
- valuesIdx := make(map[string]uint32)
- spackMetrics := make([]spackMetric, len(se.metrics.metrics))
-
- for idx, metric := range se.metrics.metrics {
- m := spackMetric{metric: metric}
-
- err := m.writeLabel(se, namesIdx, valuesIdx, metric.getNameTag(), metric.Name())
- if err != nil {
- return nil, err
- }
-
- for name, value := range metric.getLabels() {
- if err := m.writeLabel(se, namesIdx, valuesIdx, name, value); err != nil {
- return nil, err
- }
-
- }
- spackMetrics[idx] = m
- }
-
- return spackMetrics, nil
-}
-
-func (se *spackEncoder) Encode(w io.Writer) (written int, err error) {
- spackMetrics, err := se.writeLabels()
- if err != nil {
- return written, xerrors.Errorf("writeLabels failed: %w", err)
- }
-
- err = se.writeHeader(w)
- if err != nil {
- return written, xerrors.Errorf("writeHeader failed: %w", err)
- }
- written += HeaderSize
- compression := CompressionType(se.compression)
-
- cw := newCompressedWriter(w, compression)
-
- err = se.writeLabelNamesPool(cw)
- if err != nil {
- return written, xerrors.Errorf("writeLabelNamesPool failed: %w", err)
- }
-
- err = se.writeLabelValuesPool(cw)
- if err != nil {
- return written, xerrors.Errorf("writeLabelValuesPool failed: %w", err)
- }
-
- err = se.writeCommonTime(cw)
- if err != nil {
- return written, xerrors.Errorf("writeCommonTime failed: %w", err)
- }
-
- err = se.writeCommonLabels(cw)
- if err != nil {
- return written, xerrors.Errorf("writeCommonLabels failed: %w", err)
- }
-
- err = se.writeMetricsData(cw, spackMetrics)
- if err != nil {
- return written, xerrors.Errorf("writeMetricsData failed: %w", err)
- }
-
- err = cw.Close()
- if err != nil {
- return written, xerrors.Errorf("close failed: %w", err)
- }
-
- switch compression {
- case CompressionNone:
- written += cw.(*noCompressionWriteCloser).written
- case CompressionLz4:
- written += cw.(*lz4CompressionWriteCloser).written
- }
-
- return written, nil
-}
-
-func (se *spackEncoder) writeHeader(w io.Writer) error {
- if se.context.Err() != nil {
- return xerrors.Errorf("streamSpack context error: %w", se.context.Err())
- }
- ew := &errWriter{w: w}
- ew.binaryWrite(uint16(0x5053)) // Magic
- ew.binaryWrite(uint16(0x0101)) // Version
- ew.binaryWrite(uint16(24)) // HeaderSize
- ew.binaryWrite(uint8(0)) // TimePrecision(SECONDS)
- ew.binaryWrite(uint8(se.compression)) // CompressionAlg
- ew.binaryWrite(uint32(se.labelNamePool.Len())) // LabelNamesSize
- ew.binaryWrite(uint32(se.labelValuePool.Len())) // LabelValuesSize
- ew.binaryWrite(uint32(len(se.metrics.metrics))) // MetricsCount
- ew.binaryWrite(uint32(len(se.metrics.metrics))) // PointsCount
- if ew.err != nil {
- return xerrors.Errorf("binaryWrite failed: %w", ew.err)
- }
- return nil
-}
-
-func (se *spackEncoder) writeLabelNamesPool(w io.Writer) error {
- if se.context.Err() != nil {
- return xerrors.Errorf("streamSpack context error: %w", se.context.Err())
- }
- _, err := w.Write(se.labelNamePool.Bytes())
- if err != nil {
- return xerrors.Errorf("write labelNamePool failed: %w", err)
- }
- return nil
-}
-
-func (se *spackEncoder) writeLabelValuesPool(w io.Writer) error {
- if se.context.Err() != nil {
- return xerrors.Errorf("streamSpack context error: %w", se.context.Err())
- }
-
- _, err := w.Write(se.labelValuePool.Bytes())
- if err != nil {
- return xerrors.Errorf("write labelValuePool failed: %w", err)
- }
- return nil
-}
-
-func (se *spackEncoder) writeCommonTime(w io.Writer) error {
- if se.context.Err() != nil {
- return xerrors.Errorf("streamSpack context error: %w", se.context.Err())
- }
-
- if se.metrics.timestamp == nil {
- return binary.Write(w, binary.LittleEndian, uint32(0))
- }
- return binary.Write(w, binary.LittleEndian, uint32(se.metrics.timestamp.Unix()))
-}
-
-func (se *spackEncoder) writeCommonLabels(w io.Writer) error {
- if se.context.Err() != nil {
- return xerrors.Errorf("streamSpack context error: %w", se.context.Err())
- }
-
- _, err := w.Write([]byte{0})
- if err != nil {
- return xerrors.Errorf("write commonLabels failed: %w", err)
- }
- return nil
-}
-
-func (se *spackEncoder) writeMetricsData(w io.Writer, metrics []spackMetric) error {
- for _, s := range metrics {
- if se.context.Err() != nil {
- return xerrors.Errorf("streamSpack context error: %w", se.context.Err())
- }
-
- err := s.writeMetric(w)
- if err != nil {
- return xerrors.Errorf("write metric failed: %w", err)
- }
- }
- return nil
-}
diff --git a/library/go/core/metrics/solomon/spack_compression.go b/library/go/core/metrics/solomon/spack_compression.go
deleted file mode 100644
index 004fe0150d..0000000000
--- a/library/go/core/metrics/solomon/spack_compression.go
+++ /dev/null
@@ -1,162 +0,0 @@
-package solomon
-
-import (
- "encoding/binary"
- "io"
-
- "github.com/OneOfOne/xxhash"
- "github.com/pierrec/lz4"
-)
-
-type CompressionType uint8
-
-const (
- CompressionNone CompressionType = 0x0
- CompressionZlib CompressionType = 0x1
- CompressionZstd CompressionType = 0x2
- CompressionLz4 CompressionType = 0x3
-)
-
-const (
- compressionFrameLength = 512 * 1024
- hashTableSize = 64 * 1024
-)
-
-type noCompressionWriteCloser struct {
- underlying io.Writer
- written int
-}
-
-func (w *noCompressionWriteCloser) Write(p []byte) (int, error) {
- n, err := w.underlying.Write(p)
- w.written += n
- return n, err
-}
-
-func (w *noCompressionWriteCloser) Close() error {
- return nil
-}
-
-type lz4CompressionWriteCloser struct {
- underlying io.Writer
- buffer []byte
- table []int
- written int
-}
-
-func (w *lz4CompressionWriteCloser) flushFrame() (written int, err error) {
- src := w.buffer
- dst := make([]byte, lz4.CompressBlockBound(len(src)))
-
- sz, err := lz4.CompressBlock(src, dst, w.table)
- if err != nil {
- return written, err
- }
-
- if sz == 0 {
- dst = src
- } else {
- dst = dst[:sz]
- }
-
- err = binary.Write(w.underlying, binary.LittleEndian, uint32(len(dst)))
- if err != nil {
- return written, err
- }
- w.written += 4
-
- err = binary.Write(w.underlying, binary.LittleEndian, uint32(len(src)))
- if err != nil {
- return written, err
- }
- w.written += 4
-
- n, err := w.underlying.Write(dst)
- if err != nil {
- return written, err
- }
- w.written += n
-
- checksum := xxhash.Checksum32S(dst, 0x1337c0de)
- err = binary.Write(w.underlying, binary.LittleEndian, checksum)
- if err != nil {
- return written, err
- }
- w.written += 4
-
- w.buffer = w.buffer[:0]
-
- return written, nil
-}
-
-func (w *lz4CompressionWriteCloser) Write(p []byte) (written int, err error) {
- q := p[:]
- for len(q) > 0 {
- space := compressionFrameLength - len(w.buffer)
- if space == 0 {
- n, err := w.flushFrame()
- if err != nil {
- return written, err
- }
- w.written += n
- space = compressionFrameLength
- }
- length := len(q)
- if length > space {
- length = space
- }
- w.buffer = append(w.buffer, q[:length]...)
- q = q[length:]
- }
- return written, nil
-}
-
-func (w *lz4CompressionWriteCloser) Close() error {
- var err error
- if len(w.buffer) > 0 {
- n, err := w.flushFrame()
- if err != nil {
- return err
- }
- w.written += n
- }
- err = binary.Write(w.underlying, binary.LittleEndian, uint32(0))
- if err != nil {
- return nil
- }
- w.written += 4
-
- err = binary.Write(w.underlying, binary.LittleEndian, uint32(0))
- if err != nil {
- return nil
- }
- w.written += 4
-
- err = binary.Write(w.underlying, binary.LittleEndian, uint32(0))
- if err != nil {
- return nil
- }
- w.written += 4
-
- return nil
-}
-
-func newCompressedWriter(w io.Writer, compression CompressionType) io.WriteCloser {
- switch compression {
- case CompressionNone:
- return &noCompressionWriteCloser{w, 0}
- case CompressionZlib:
- panic("zlib compression not supported")
- case CompressionZstd:
- panic("zstd compression not supported")
- case CompressionLz4:
- return &lz4CompressionWriteCloser{
- w,
- make([]byte, 0, compressionFrameLength),
- make([]int, hashTableSize),
- 0,
- }
- default:
- panic("unsupported compression algorithm")
- }
-}
diff --git a/library/go/core/metrics/solomon/stream.go b/library/go/core/metrics/solomon/stream.go
deleted file mode 100644
index 26dc768c98..0000000000
--- a/library/go/core/metrics/solomon/stream.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package solomon
-
-import (
- "context"
- "encoding/json"
- "io"
-
- "a.yandex-team.ru/library/go/core/xerrors"
-)
-
-const HeaderSize = 24
-
-type StreamFormat string
-
-func (r *Registry) StreamJSON(ctx context.Context, w io.Writer) (written int, err error) {
- cw := newCompressedWriter(w, CompressionNone)
-
- if ctx.Err() != nil {
- return written, xerrors.Errorf("streamJSON context error: %w", ctx.Err())
- }
- _, err = cw.Write([]byte("{\"metrics\":["))
- if err != nil {
- return written, xerrors.Errorf("write metrics failed: %w", err)
- }
-
- first := true
- r.metrics.Range(func(_, s interface{}) bool {
- if ctx.Err() != nil {
- err = xerrors.Errorf("streamJSON context error: %w", ctx.Err())
- return false
- }
-
- // write trailing comma
- if !first {
- _, err = cw.Write([]byte(","))
- if err != nil {
- err = xerrors.Errorf("write metrics failed: %w", err)
- return false
- }
- }
-
- var b []byte
-
- b, err = json.Marshal(s)
- if err != nil {
- err = xerrors.Errorf("marshal metric failed: %w", err)
- return false
- }
-
- // write metric json
- _, err = cw.Write(b)
- if err != nil {
- err = xerrors.Errorf("write metric failed: %w", err)
- return false
- }
-
- first = false
- return true
- })
- if err != nil {
- return written, err
- }
-
- if ctx.Err() != nil {
- return written, xerrors.Errorf("streamJSON context error: %w", ctx.Err())
- }
- _, err = cw.Write([]byte("]}"))
- if err != nil {
- return written, xerrors.Errorf("write metrics failed: %w", err)
- }
-
- if ctx.Err() != nil {
- return written, xerrors.Errorf("streamJSON context error: %w", ctx.Err())
- }
- err = cw.Close()
- if err != nil {
- return written, xerrors.Errorf("close failed: %w", err)
- }
-
- return cw.(*noCompressionWriteCloser).written, nil
-}
-
-func (r *Registry) StreamSpack(ctx context.Context, w io.Writer, compression CompressionType) (int, error) {
- metrics, err := r.Gather()
- if err != nil {
- return 0, err
- }
- return NewSpackEncoder(ctx, compression, metrics).Encode(w)
-}
diff --git a/library/go/core/metrics/solomon/timer.go b/library/go/core/metrics/solomon/timer.go
deleted file mode 100644
index b26acc490b..0000000000
--- a/library/go/core/metrics/solomon/timer.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package solomon
-
-import (
- "encoding/json"
- "time"
-
- "go.uber.org/atomic"
-
- "a.yandex-team.ru/library/go/core/metrics"
-)
-
-var (
- _ metrics.Timer = (*Timer)(nil)
- _ Metric = (*Timer)(nil)
-)
-
-// Timer measures gauge duration.
-type Timer struct {
- name string
- metricType metricType
- tags map[string]string
- value atomic.Duration
- timestamp *time.Time
-
- useNameTag bool
-}
-
-func (t *Timer) RecordDuration(value time.Duration) {
- t.value.Store(value)
-}
-
-func (t *Timer) Name() string {
- return t.name
-}
-
-func (t *Timer) getType() metricType {
- return t.metricType
-}
-
-func (t *Timer) getLabels() map[string]string {
- return t.tags
-}
-
-func (t *Timer) getValue() interface{} {
- return t.value.Load().Seconds()
-}
-
-func (t *Timer) getTimestamp() *time.Time {
- return t.timestamp
-}
-
-func (t *Timer) getNameTag() string {
- if t.useNameTag {
- return "name"
- } else {
- return "sensor"
- }
-}
-
-// MarshalJSON implements json.Marshaler.
-func (t *Timer) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string `json:"type"`
- Labels map[string]string `json:"labels"`
- Value float64 `json:"value"`
- Timestamp *int64 `json:"ts,omitempty"`
- }{
- Type: t.metricType.String(),
- Value: t.value.Load().Seconds(),
- Labels: func() map[string]string {
- labels := make(map[string]string, len(t.tags)+1)
- labels[t.getNameTag()] = t.Name()
- for k, v := range t.tags {
- labels[k] = v
- }
- return labels
- }(),
- Timestamp: tsAsRef(t.timestamp),
- })
-}
-
-// Snapshot returns independent copy on metric.
-func (t *Timer) Snapshot() Metric {
- return &Timer{
- name: t.name,
- metricType: t.metricType,
- tags: t.tags,
- value: *atomic.NewDuration(t.value.Load()),
-
- useNameTag: t.useNameTag,
- }
-}
diff --git a/library/go/core/metrics/solomon/vec.go b/library/go/core/metrics/solomon/vec.go
deleted file mode 100644
index a4d3ab1a83..0000000000
--- a/library/go/core/metrics/solomon/vec.go
+++ /dev/null
@@ -1,226 +0,0 @@
-package solomon
-
-import (
- "sync"
-
- "a.yandex-team.ru/library/go/core/metrics"
- "a.yandex-team.ru/library/go/core/metrics/internal/pkg/registryutil"
-)
-
-// metricsVector is a base implementation of vector of metrics of any supported type.
-type metricsVector struct {
- labels []string
- mtx sync.RWMutex // Protects metrics.
- metrics map[uint64]Metric
- rated bool
- newMetric func(map[string]string) Metric
-}
-
-func (v *metricsVector) with(tags map[string]string) Metric {
- hv, err := registryutil.VectorHash(tags, v.labels)
- if err != nil {
- panic(err)
- }
-
- v.mtx.RLock()
- metric, ok := v.metrics[hv]
- v.mtx.RUnlock()
- if ok {
- return metric
- }
-
- v.mtx.Lock()
- defer v.mtx.Unlock()
-
- metric, ok = v.metrics[hv]
- if !ok {
- metric = v.newMetric(tags)
- v.metrics[hv] = metric
- }
-
- return metric
-}
-
-// reset deletes all metrics in this vector.
-func (v *metricsVector) reset() {
- v.mtx.Lock()
- defer v.mtx.Unlock()
-
- for h := range v.metrics {
- delete(v.metrics, h)
- }
-}
-
-var _ metrics.CounterVec = (*CounterVec)(nil)
-
-// CounterVec stores counters and
-// implements metrics.CounterVec interface.
-type CounterVec struct {
- vec *metricsVector
-}
-
-// CounterVec creates a new counters vector with given metric name and
-// partitioned by the given label names.
-func (r *Registry) CounterVec(name string, labels []string) metrics.CounterVec {
- var vec *metricsVector
- vec = &metricsVector{
- labels: append([]string(nil), labels...),
- metrics: make(map[uint64]Metric),
- rated: r.rated,
- newMetric: func(tags map[string]string) Metric {
- return r.Rated(vec.rated).
- WithTags(tags).
- Counter(name).(*Counter)
- },
- }
- return &CounterVec{vec: vec}
-}
-
-// With creates new or returns existing counter with given tags from vector.
-// It will panic if tags keys set is not equal to vector labels.
-func (v *CounterVec) With(tags map[string]string) metrics.Counter {
- return v.vec.with(tags).(*Counter)
-}
-
-// Reset deletes all metrics in this vector.
-func (v *CounterVec) Reset() {
- v.vec.reset()
-}
-
-var _ metrics.GaugeVec = (*GaugeVec)(nil)
-
-// GaugeVec stores gauges and
-// implements metrics.GaugeVec interface.
-type GaugeVec struct {
- vec *metricsVector
-}
-
-// GaugeVec creates a new gauges vector with given metric name and
-// partitioned by the given label names.
-func (r *Registry) GaugeVec(name string, labels []string) metrics.GaugeVec {
- return &GaugeVec{
- vec: &metricsVector{
- labels: append([]string(nil), labels...),
- metrics: make(map[uint64]Metric),
- newMetric: func(tags map[string]string) Metric {
- return r.WithTags(tags).Gauge(name).(*Gauge)
- },
- },
- }
-}
-
-// With creates new or returns existing gauge with given tags from vector.
-// It will panic if tags keys set is not equal to vector labels.
-func (v *GaugeVec) With(tags map[string]string) metrics.Gauge {
- return v.vec.with(tags).(*Gauge)
-}
-
-// Reset deletes all metrics in this vector.
-func (v *GaugeVec) Reset() {
- v.vec.reset()
-}
-
-var _ metrics.TimerVec = (*TimerVec)(nil)
-
-// TimerVec stores timers and
-// implements metrics.TimerVec interface.
-type TimerVec struct {
- vec *metricsVector
-}
-
-// TimerVec creates a new timers vector with given metric name and
-// partitioned by the given label names.
-func (r *Registry) TimerVec(name string, labels []string) metrics.TimerVec {
- return &TimerVec{
- vec: &metricsVector{
- labels: append([]string(nil), labels...),
- metrics: make(map[uint64]Metric),
- newMetric: func(tags map[string]string) Metric {
- return r.WithTags(tags).Timer(name).(*Timer)
- },
- },
- }
-}
-
-// With creates new or returns existing timer with given tags from vector.
-// It will panic if tags keys set is not equal to vector labels.
-func (v *TimerVec) With(tags map[string]string) metrics.Timer {
- return v.vec.with(tags).(*Timer)
-}
-
-// Reset deletes all metrics in this vector.
-func (v *TimerVec) Reset() {
- v.vec.reset()
-}
-
-var _ metrics.HistogramVec = (*HistogramVec)(nil)
-
-// HistogramVec stores histograms and
-// implements metrics.HistogramVec interface.
-type HistogramVec struct {
- vec *metricsVector
-}
-
-// HistogramVec creates a new histograms vector with given metric name and buckets and
-// partitioned by the given label names.
-func (r *Registry) HistogramVec(name string, buckets metrics.Buckets, labels []string) metrics.HistogramVec {
- var vec *metricsVector
- vec = &metricsVector{
- labels: append([]string(nil), labels...),
- metrics: make(map[uint64]Metric),
- rated: r.rated,
- newMetric: func(tags map[string]string) Metric {
- return r.Rated(vec.rated).
- WithTags(tags).
- Histogram(name, buckets).(*Histogram)
- },
- }
- return &HistogramVec{vec: vec}
-}
-
-// With creates new or returns existing histogram with given tags from vector.
-// It will panic if tags keys set is not equal to vector labels.
-func (v *HistogramVec) With(tags map[string]string) metrics.Histogram {
- return v.vec.with(tags).(*Histogram)
-}
-
-// Reset deletes all metrics in this vector.
-func (v *HistogramVec) Reset() {
- v.vec.reset()
-}
-
-var _ metrics.TimerVec = (*DurationHistogramVec)(nil)
-
-// DurationHistogramVec stores duration histograms and
-// implements metrics.TimerVec interface.
-type DurationHistogramVec struct {
- vec *metricsVector
-}
-
-// DurationHistogramVec creates a new duration histograms vector with given metric name and buckets and
-// partitioned by the given label names.
-func (r *Registry) DurationHistogramVec(name string, buckets metrics.DurationBuckets, labels []string) metrics.TimerVec {
- var vec *metricsVector
- vec = &metricsVector{
- labels: append([]string(nil), labels...),
- metrics: make(map[uint64]Metric),
- rated: r.rated,
- newMetric: func(tags map[string]string) Metric {
- return r.Rated(vec.rated).
- WithTags(tags).
- DurationHistogram(name, buckets).(*Histogram)
- },
- }
- return &DurationHistogramVec{vec: vec}
-}
-
-// With creates new or returns existing duration histogram with given tags from vector.
-// It will panic if tags keys set is not equal to vector labels.
-func (v *DurationHistogramVec) With(tags map[string]string) metrics.Timer {
- return v.vec.with(tags).(*Histogram)
-}
-
-// Reset deletes all metrics in this vector.
-func (v *DurationHistogramVec) Reset() {
- v.vec.reset()
-}