Compare commits
9 Commits
d783709a53
...
4e491639e6
Author | SHA1 | Date | |
---|---|---|---|
4e491639e6 | |||
cfcb00051e | |||
6aa41f4081 | |||
|
a5eb7684ff | ||
|
880d8e1cc6 | ||
|
4a30cca184 | ||
|
8969e845c9 | ||
|
8466104303 | ||
|
60fb01a811 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.idea/
|
@ -2,7 +2,7 @@ package metrics_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"go.unistack.org/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleCounter() {
|
func ExampleCounter() {
|
||||||
|
@ -2,7 +2,7 @@ package metrics_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"go.unistack.org/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleFloatCounter() {
|
func ExampleFloatCounter() {
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"go.unistack.org/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleGauge() {
|
func ExampleGauge() {
|
||||||
|
2
go.mod
2
go.mod
@ -1,4 +1,4 @@
|
|||||||
module github.com/VictoriaMetrics/metrics
|
module go.unistack.org/metrics
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/valyala/histogram v1.2.0
|
github.com/valyala/histogram v1.2.0
|
||||||
|
@ -36,7 +36,7 @@ func initSupportedRuntimeMetrics(rms [][2]string) [][2]string {
|
|||||||
if _, ok := exposedMetrics[metricName]; ok {
|
if _, ok := exposedMetrics[metricName]; ok {
|
||||||
supportedMetrics = append(supportedMetrics, rm)
|
supportedMetrics = append(supportedMetrics, rm)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("github.com/VictoriaMetrics/metrics: do not expose %s metric, since the corresponding metric %s isn't supported in the current Go runtime", rm[1], metricName)
|
log.Printf("go.unistack.org/metrics: do not expose %s metric, since the corresponding metric %s isn't supported in the current Go runtime", rm[1], metricName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return supportedMetrics
|
return supportedMetrics
|
||||||
|
56
histogram.go
56
histogram.go
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -63,6 +64,8 @@ type Histogram struct {
|
|||||||
|
|
||||||
// sum is the sum of all the values put into Histogram
|
// sum is the sum of all the values put into Histogram
|
||||||
sum float64
|
sum float64
|
||||||
|
|
||||||
|
compatible bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets the given histogram.
|
// Reset resets the given histogram.
|
||||||
@ -82,6 +85,14 @@ func (h *Histogram) Reset() {
|
|||||||
h.mu.Unlock()
|
h.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Histogram) GetSum() float64 {
|
||||||
|
return h.sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Histogram) GetDecimalBuckets() [decimalBucketsCount]*[bucketsPerDecimal]uint64 {
|
||||||
|
return h.decimalBuckets
|
||||||
|
}
|
||||||
|
|
||||||
// Update updates h with v.
|
// Update updates h with v.
|
||||||
//
|
//
|
||||||
// Negative values and NaNs are ignored.
|
// Negative values and NaNs are ignored.
|
||||||
@ -187,6 +198,9 @@ func (h *Histogram) VisitNonZeroBuckets(f func(vmrange string, count uint64)) {
|
|||||||
func NewHistogram(name string) *Histogram {
|
func NewHistogram(name string) *Histogram {
|
||||||
return defaultSet.NewHistogram(name)
|
return defaultSet.NewHistogram(name)
|
||||||
}
|
}
|
||||||
|
func NewCompatibleHistogram(name string) *Histogram {
|
||||||
|
return defaultSet.NewCompatibleHistogram(name)
|
||||||
|
}
|
||||||
|
|
||||||
// GetOrCreateHistogram returns registered histogram with the given name
|
// GetOrCreateHistogram returns registered histogram with the given name
|
||||||
// or creates new histogram if the registry doesn't contain histogram with
|
// or creates new histogram if the registry doesn't contain histogram with
|
||||||
@ -205,6 +219,9 @@ func NewHistogram(name string) *Histogram {
|
|||||||
func GetOrCreateHistogram(name string) *Histogram {
|
func GetOrCreateHistogram(name string) *Histogram {
|
||||||
return defaultSet.GetOrCreateHistogram(name)
|
return defaultSet.GetOrCreateHistogram(name)
|
||||||
}
|
}
|
||||||
|
func GetOrCreateCompatibleHistogram(name string) *Histogram {
|
||||||
|
return defaultSet.GetOrCreateCompatibleHistogram(name)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateDuration updates request duration based on the given startTime.
|
// UpdateDuration updates request duration based on the given startTime.
|
||||||
func (h *Histogram) UpdateDuration(startTime time.Time) {
|
func (h *Histogram) UpdateDuration(startTime time.Time) {
|
||||||
@ -237,6 +254,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (h *Histogram) marshalTo(prefix string, w io.Writer) {
|
func (h *Histogram) marshalTo(prefix string, w io.Writer) {
|
||||||
|
if h.compatible {
|
||||||
|
h.marshalToPrometheus(prefix, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
countTotal := uint64(0)
|
countTotal := uint64(0)
|
||||||
h.VisitNonZeroBuckets(func(vmrange string, count uint64) {
|
h.VisitNonZeroBuckets(func(vmrange string, count uint64) {
|
||||||
tag := fmt.Sprintf("vmrange=%q", vmrange)
|
tag := fmt.Sprintf("vmrange=%q", vmrange)
|
||||||
@ -257,6 +278,41 @@ func (h *Histogram) marshalTo(prefix string, w io.Writer) {
|
|||||||
}
|
}
|
||||||
fmt.Fprintf(w, "%s_count%s %d\n", name, labels, countTotal)
|
fmt.Fprintf(w, "%s_count%s %d\n", name, labels, countTotal)
|
||||||
}
|
}
|
||||||
|
func (h *Histogram) marshalToPrometheus(prefix string, w io.Writer) {
|
||||||
|
countTotal := uint64(0)
|
||||||
|
inf := false
|
||||||
|
h.VisitNonZeroBuckets(func(vmrange string, count uint64) {
|
||||||
|
v := strings.Split(vmrange, "...")
|
||||||
|
if len(v) != 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if v[1] == "+Inf" {
|
||||||
|
inf = true
|
||||||
|
}
|
||||||
|
tag := fmt.Sprintf("le=%q", v[1])
|
||||||
|
metricName := addTag(prefix, tag)
|
||||||
|
name, labels := splitMetricName(metricName)
|
||||||
|
countTotal += count
|
||||||
|
fmt.Fprintf(w, "%s_bucket%s %d\n", name, labels, countTotal)
|
||||||
|
})
|
||||||
|
if countTotal == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !inf {
|
||||||
|
tag := fmt.Sprintf("le=%q", "+Inf")
|
||||||
|
metricName := addTag(prefix, tag)
|
||||||
|
name, labels := splitMetricName(metricName)
|
||||||
|
fmt.Fprintf(w, "%s_bucket%s %d\n", name, labels, countTotal)
|
||||||
|
}
|
||||||
|
name, labels := splitMetricName(prefix)
|
||||||
|
sum := h.getSum()
|
||||||
|
if float64(int64(sum)) == sum {
|
||||||
|
fmt.Fprintf(w, "%s_sum%s %d\n", name, labels, int64(sum))
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, "%s_sum%s %g\n", name, labels, sum)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "%s_count%s %d\n", name, labels, countTotal)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Histogram) getSum() float64 {
|
func (h *Histogram) getSum() float64 {
|
||||||
h.mu.Lock()
|
h.mu.Lock()
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"go.unistack.org/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleHistogram() {
|
func ExampleHistogram() {
|
||||||
|
@ -3,7 +3,7 @@ package metrics_test
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"go.unistack.org/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleWritePrometheus() {
|
func ExampleWritePrometheus() {
|
||||||
|
@ -99,10 +99,10 @@ func writeIOMetrics(w io.Writer) {
|
|||||||
data, err := ioutil.ReadFile(ioFilepath)
|
data, err := ioutil.ReadFile(ioFilepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Do not spam the logs with errors - this error cannot be fixed without process restart.
|
// Do not spam the logs with errors - this error cannot be fixed without process restart.
|
||||||
// See https://github.com/VictoriaMetrics/metrics/issues/42
|
// See https://go.unistack.org/metrics/issues/42
|
||||||
if atomic.CompareAndSwapUint32(&procSelfIOErrLogged, 0, 1) {
|
if atomic.CompareAndSwapUint32(&procSelfIOErrLogged, 0, 1) {
|
||||||
log.Printf("ERROR: metrics: cannot read process_io_* metrics from %q, so these metrics won't be updated until the error is fixed; "+
|
log.Printf("ERROR: metrics: cannot read process_io_* metrics from %q, so these metrics won't be updated until the error is fixed; "+
|
||||||
"see https://github.com/VictoriaMetrics/metrics/issues/42 ; The error: %s", ioFilepath, err)
|
"see https://go.unistack.org/metrics/issues/42 ; The error: %s", ioFilepath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
33
set.go
33
set.go
@ -85,6 +85,11 @@ func (s *Set) NewHistogram(name string) *Histogram {
|
|||||||
s.registerMetric(name, h)
|
s.registerMetric(name, h)
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
func (s *Set) NewCompatibleHistogram(name string) *Histogram {
|
||||||
|
h := &Histogram{compatible: true}
|
||||||
|
s.registerMetric(name, h)
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
// GetOrCreateHistogram returns registered histogram in s with the given name
|
// GetOrCreateHistogram returns registered histogram in s with the given name
|
||||||
// or creates new histogram if s doesn't contain histogram with the given name.
|
// or creates new histogram if s doesn't contain histogram with the given name.
|
||||||
@ -127,6 +132,34 @@ func (s *Set) GetOrCreateHistogram(name string) *Histogram {
|
|||||||
}
|
}
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
func (s *Set) GetOrCreateCompatibleHistogram(name string) *Histogram {
|
||||||
|
s.mu.Lock()
|
||||||
|
nm := s.m[name]
|
||||||
|
s.mu.Unlock()
|
||||||
|
if nm == nil {
|
||||||
|
// Slow path - create and register missing histogram.
|
||||||
|
if err := validateMetric(name); err != nil {
|
||||||
|
panic(fmt.Errorf("BUG: invalid metric name %q: %s", name, err))
|
||||||
|
}
|
||||||
|
nmNew := &namedMetric{
|
||||||
|
name: name,
|
||||||
|
metric: &Histogram{compatible: true},
|
||||||
|
}
|
||||||
|
s.mu.Lock()
|
||||||
|
nm = s.m[name]
|
||||||
|
if nm == nil {
|
||||||
|
nm = nmNew
|
||||||
|
s.m[name] = nm
|
||||||
|
s.a = append(s.a, nm)
|
||||||
|
}
|
||||||
|
s.mu.Unlock()
|
||||||
|
}
|
||||||
|
h, ok := nm.metric.(*Histogram)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Errorf("BUG: metric %q isn't a Histogram. It is %T", name, nm.metric))
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
// NewCounter registers and returns new counter with the given name in the s.
|
// NewCounter registers and returns new counter with the given name in the s.
|
||||||
//
|
//
|
||||||
|
@ -3,7 +3,7 @@ package metrics_test
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"go.unistack.org/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleSet() {
|
func ExampleSet() {
|
||||||
|
20
summary.go
20
summary.go
@ -31,6 +31,26 @@ type Summary struct {
|
|||||||
window time.Duration
|
window time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Summary) GetSum() float64 {
|
||||||
|
return s.sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Summary) GetCount() uint64 {
|
||||||
|
return s.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Summary) GetTime() time.Duration {
|
||||||
|
return s.window
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Summary) GetQuantiles() []float64 {
|
||||||
|
return s.quantiles
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Summary) GetQuantileValues() []float64 {
|
||||||
|
return s.quantileValues
|
||||||
|
}
|
||||||
|
|
||||||
// NewSummary creates and returns new summary with the given name.
|
// NewSummary creates and returns new summary with the given name.
|
||||||
//
|
//
|
||||||
// name must be valid Prometheus-compatible metric with possible labels.
|
// name must be valid Prometheus-compatible metric with possible labels.
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/metrics"
|
"go.unistack.org/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleSummary() {
|
func ExampleSummary() {
|
||||||
|
Loading…
Reference in New Issue
Block a user