mirror of
https://github.com/nabbar/golib.git
synced 2025-10-17 13:21:36 +08:00
Add package prometheus
This commit is contained in:
99
prometheus/bloom.go
Normal file
99
prometheus/bloom.go
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Nicolas JUHEL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/bits-and-blooms/bitset"
|
||||
)
|
||||
|
||||
const defaultSize = 2 << 24
|
||||
|
||||
var seeds = []uint{7, 11, 13, 31, 37, 61}
|
||||
|
||||
type bloomFilter struct {
|
||||
m sync.Mutex
|
||||
Set *bitset.BitSet
|
||||
Funcs [6]simpleHash
|
||||
}
|
||||
|
||||
type BloomFilter interface {
|
||||
Add(value string)
|
||||
Contains(value string) bool
|
||||
}
|
||||
|
||||
func NewBloomFilter() BloomFilter {
|
||||
bf := new(bloomFilter)
|
||||
|
||||
for i := 0; i < len(bf.Funcs); i++ {
|
||||
bf.Funcs[i] = simpleHash{defaultSize, seeds[i]}
|
||||
}
|
||||
|
||||
bf.Set = bitset.New(defaultSize)
|
||||
|
||||
return bf
|
||||
}
|
||||
|
||||
func (bf *bloomFilter) Add(value string) {
|
||||
bf.m.Lock()
|
||||
defer bf.m.Unlock()
|
||||
|
||||
for _, f := range bf.Funcs {
|
||||
bf.Set.Set(f.hash(value))
|
||||
}
|
||||
}
|
||||
|
||||
func (bf *bloomFilter) Contains(value string) bool {
|
||||
if value == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
ret := true
|
||||
|
||||
bf.m.Lock()
|
||||
defer bf.m.Unlock()
|
||||
|
||||
for _, f := range bf.Funcs {
|
||||
ret = ret && bf.Set.Test(f.hash(value))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
type simpleHash struct {
|
||||
Cap uint
|
||||
Seed uint
|
||||
}
|
||||
|
||||
func (s *simpleHash) hash(value string) uint {
|
||||
var result uint = 0
|
||||
for i := 0; i < len(value); i++ {
|
||||
result = result*s.Seed + uint(value[i])
|
||||
}
|
||||
return (s.Cap - 1) & result
|
||||
}
|
67
prometheus/interface.go
Normal file
67
prometheus/interface.go
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Nicolas JUHEL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultSlowTime = int32(5)
|
||||
)
|
||||
|
||||
type Prometheus interface {
|
||||
Expose(c *gin.Context)
|
||||
MiddleWare(c *gin.Context)
|
||||
CollectMetrics(c *gin.Context, start time.Time)
|
||||
|
||||
ExcludePath(startWith ...string)
|
||||
|
||||
GetMetric(name string) *metrics
|
||||
SetMetric(metric Metrics) error
|
||||
AddMetric(metric Metrics) error
|
||||
ListMetric() []string
|
||||
|
||||
SetSlowTime(slowTime int32)
|
||||
GetSlowTime() int32
|
||||
|
||||
SetDuration(duration []float64)
|
||||
GetDuration() []float64
|
||||
}
|
||||
|
||||
// New will return a new object that implement interface GinPrometheus.
|
||||
func New() Prometheus {
|
||||
return &monitor{
|
||||
slowTime: DefaultSlowTime,
|
||||
reqDuration: []float64{0.1, 0.3, 1.2, 5, 10},
|
||||
metrics: make(map[string]*atomic.Value),
|
||||
exclude: make([]string, 0),
|
||||
}
|
||||
}
|
239
prometheus/metrics.go
Normal file
239
prometheus/metrics.go
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Nicolas JUHEL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type Metrics interface {
|
||||
SetGaugeValue(labelValues []string, value float64) error
|
||||
Inc(labelValues []string) error
|
||||
Add(labelValues []string, value float64) error
|
||||
Observe(labelValues []string, value float64) error
|
||||
|
||||
Collect(c *gin.Context, start time.Time)
|
||||
|
||||
GetName() string
|
||||
GetType() MetricType
|
||||
SetDesc(desc string)
|
||||
|
||||
AddLabel(label ...string)
|
||||
AddBuckets(bucket ...float64)
|
||||
AddObjective(key, value float64)
|
||||
SetCollect(fct FuncCollect)
|
||||
}
|
||||
|
||||
type FuncCollect func(m Metrics, c *gin.Context, start time.Time)
|
||||
|
||||
func NewMetrics(name string, metricType MetricType) Metrics {
|
||||
return &metrics{
|
||||
t: metricType,
|
||||
n: name,
|
||||
d: "",
|
||||
l: make([]string, 0),
|
||||
b: make([]float64, 0),
|
||||
o: make(map[float64]float64, 0),
|
||||
f: nil,
|
||||
v: nil,
|
||||
}
|
||||
}
|
||||
|
||||
// metrics defines a metric object. Users can use it to save
|
||||
// metric data. Every metric should be globally unique by name.
|
||||
type metrics struct {
|
||||
m sync.Mutex
|
||||
t MetricType
|
||||
n string
|
||||
d string
|
||||
l []string
|
||||
b []float64
|
||||
o map[float64]float64
|
||||
f FuncCollect
|
||||
v prometheus.Collector
|
||||
}
|
||||
|
||||
// SetGaugeValue set data for Gauge type metrics.
|
||||
func (m *metrics) SetGaugeValue(labelValues []string, value float64) error {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if m.t == None {
|
||||
return errors.Errorf("metric '%s' not existed.", m.n)
|
||||
}
|
||||
|
||||
if m.t != Gauge {
|
||||
return errors.Errorf("metric '%s' not Gauge type", m.n)
|
||||
}
|
||||
|
||||
m.v.(*prometheus.GaugeVec).WithLabelValues(labelValues...).Set(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Inc increases value for Counter/Gauge type metric, increments
|
||||
// the counter by 1
|
||||
func (m *metrics) Inc(labelValues []string) error {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if m.t == None {
|
||||
return errors.Errorf("metric '%s' not existed.", m.n)
|
||||
}
|
||||
|
||||
if m.t != Gauge && m.t != Counter {
|
||||
return errors.Errorf("metric '%s' not Gauge or Counter type", m.n)
|
||||
}
|
||||
|
||||
switch m.t {
|
||||
case Counter:
|
||||
m.v.(*prometheus.CounterVec).WithLabelValues(labelValues...).Inc()
|
||||
break
|
||||
case Gauge:
|
||||
m.v.(*prometheus.GaugeVec).WithLabelValues(labelValues...).Inc()
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Add adds the given value to the metrics object. Only
|
||||
// for Counter/Gauge type metric.
|
||||
func (m *metrics) Add(labelValues []string, value float64) error {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if m.t == None {
|
||||
return errors.Errorf("metric '%s' not existed.", m.n)
|
||||
}
|
||||
|
||||
if m.t != Gauge && m.t != Counter {
|
||||
return errors.Errorf("metric '%s' not Gauge or Counter type", m.n)
|
||||
}
|
||||
|
||||
switch m.t {
|
||||
case Counter:
|
||||
m.v.(*prometheus.CounterVec).WithLabelValues(labelValues...).Add(value)
|
||||
break
|
||||
case Gauge:
|
||||
m.v.(*prometheus.GaugeVec).WithLabelValues(labelValues...).Add(value)
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Observe is used by Histogram and Summary type metric to
|
||||
// add observations.
|
||||
func (m *metrics) Observe(labelValues []string, value float64) error {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if m.t == 0 {
|
||||
return errors.Errorf("metric '%s' not existed.", m.n)
|
||||
}
|
||||
|
||||
if m.t != Histogram && m.t != Summary {
|
||||
return errors.Errorf("metric '%s' not Histogram or Summary type", m.n)
|
||||
}
|
||||
|
||||
switch m.t {
|
||||
case Histogram:
|
||||
m.v.(*prometheus.HistogramVec).WithLabelValues(labelValues...).Observe(value)
|
||||
break
|
||||
case Summary:
|
||||
m.v.(*prometheus.SummaryVec).WithLabelValues(labelValues...).Observe(value)
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *metrics) Collect(c *gin.Context, start time.Time) {
|
||||
if m.f != nil {
|
||||
m.f(m, c, start)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *metrics) GetName() string {
|
||||
return m.n
|
||||
}
|
||||
|
||||
func (m *metrics) GetType() MetricType {
|
||||
return m.t
|
||||
}
|
||||
|
||||
func (m *metrics) SetDesc(desc string) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
m.d = desc
|
||||
}
|
||||
|
||||
func (m *metrics) AddLabel(label ...string) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if len(m.l) < 1 {
|
||||
m.l = make([]string, 0)
|
||||
}
|
||||
|
||||
m.l = append(m.l, label...)
|
||||
}
|
||||
|
||||
func (m *metrics) AddBuckets(bucket ...float64) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if len(m.b) < 1 {
|
||||
m.b = make([]float64, 0)
|
||||
}
|
||||
|
||||
m.b = append(m.b, bucket...)
|
||||
}
|
||||
|
||||
func (m *metrics) AddObjective(key, value float64) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if len(m.o) < 1 {
|
||||
m.o = make(map[float64]float64, 0)
|
||||
}
|
||||
|
||||
m.o[key] = value
|
||||
}
|
||||
|
||||
func (m *metrics) SetCollect(fct FuncCollect) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
m.f = fct
|
||||
}
|
209
prometheus/monitor.go
Normal file
209
prometheus/monitor.go
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Nicolas JUHEL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
// GinPrometheus is an object that uses to set gin server monitor.
|
||||
type monitor struct {
|
||||
m sync.Mutex
|
||||
|
||||
exclude []string
|
||||
slowTime int32
|
||||
reqDuration []float64
|
||||
|
||||
metrics map[string]*atomic.Value
|
||||
}
|
||||
|
||||
// Expose adds metric path to a given router.
|
||||
// The router can be different with the one passed to UseWithoutExposingEndpoint.
|
||||
// This allows to expose metrics on different port.
|
||||
func (m *monitor) Expose(c *gin.Context) {
|
||||
promhttp.Handler().ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
|
||||
// MiddleWare as gin monitor middleware.
|
||||
func (m *monitor) MiddleWare(c *gin.Context) {
|
||||
startTime := time.Now()
|
||||
|
||||
if len(m.exclude) > 0 {
|
||||
r := c.Request.URL.Path
|
||||
if !strings.HasPrefix(r, "/") {
|
||||
r = "/" + r
|
||||
}
|
||||
for _, p := range m.exclude {
|
||||
if p != "" && strings.HasPrefix(r, p) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// execute normal process.
|
||||
c.Next()
|
||||
|
||||
// after request
|
||||
m.CollectMetrics(c, startTime)
|
||||
}
|
||||
|
||||
func (m *monitor) CollectMetrics(c *gin.Context, start time.Time) {
|
||||
for _, k := range m.ListMetric() {
|
||||
metric := m.GetMetric(k)
|
||||
metric.Collect(c, start)
|
||||
_ = m.SetMetric(metric)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *monitor) ExcludePath(startWith ...string) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
for _, p := range startWith {
|
||||
if p != "" {
|
||||
m.exclude = append(m.exclude, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetSlowTime set slowTime property. slowTime is used to determine whether
|
||||
// the request is slow. For "gin_slow_request_total" metric.
|
||||
func (m *monitor) SetSlowTime(slowTime int32) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
m.slowTime = slowTime
|
||||
}
|
||||
|
||||
// GetSlowTime retrieve the slowTime property. slowTime is used to determine whether
|
||||
// the request is slow. For "gin_slow_request_total" metric.
|
||||
func (m *monitor) GetSlowTime() int32 {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
return m.slowTime
|
||||
}
|
||||
|
||||
// SetDuration set duration property. duration is used to ginRequestDuration
|
||||
// metric buckets.
|
||||
func (m *monitor) SetDuration(duration []float64) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
m.reqDuration = duration
|
||||
}
|
||||
|
||||
// GetDuration retrieve the duration property. duration is used to ginRequestDuration
|
||||
// metric buckets.
|
||||
func (m *monitor) GetDuration() []float64 {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
return m.reqDuration
|
||||
}
|
||||
|
||||
// GetMetric used to get metric object by metric_name.
|
||||
func (m *monitor) GetMetric(name string) *metrics {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
if a, ok := m.metrics[name]; !ok || a == nil {
|
||||
return &metrics{}
|
||||
} else if i := a.Load(); i == nil {
|
||||
return &metrics{}
|
||||
} else if o, ok := i.(*metrics); !ok || o == nil {
|
||||
return &metrics{}
|
||||
} else {
|
||||
return o
|
||||
}
|
||||
}
|
||||
|
||||
// SetMetric used to store an atomic value of the metric object by metric_name.
|
||||
func (m *monitor) SetMetric(metric Metrics) error {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
var (
|
||||
ok bool
|
||||
o *metrics
|
||||
)
|
||||
|
||||
if o, ok = metric.(*metrics); !ok {
|
||||
return errors.Errorf("metric is not a valid metric instance")
|
||||
}
|
||||
|
||||
if o.n == "" {
|
||||
return errors.Errorf("metric name cannot be empty.")
|
||||
}
|
||||
|
||||
if o.f == nil {
|
||||
return errors.Errorf("metric collect func cannot be empty.")
|
||||
}
|
||||
|
||||
if _, ok = m.metrics[o.n]; !ok {
|
||||
if err := o.t.Register(o); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
prometheus.MustRegister(o.v)
|
||||
}
|
||||
|
||||
if m.metrics[o.n] == nil {
|
||||
m.metrics[o.n] = new(atomic.Value)
|
||||
}
|
||||
|
||||
m.metrics[o.n].Store(metric)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddMetric add custom monitor metric.
|
||||
func (m *monitor) AddMetric(metric Metrics) error {
|
||||
return m.SetMetric(metric)
|
||||
}
|
||||
|
||||
// ListMetric retrieve a slice of metrics' name registered
|
||||
func (m *monitor) ListMetric() []string {
|
||||
var res = make([]string, 0)
|
||||
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
for k := range m.metrics {
|
||||
res = append(res, k)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
95
prometheus/types.go
Normal file
95
prometheus/types.go
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Nicolas JUHEL
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type MetricType int
|
||||
|
||||
const (
|
||||
None MetricType = iota
|
||||
Counter
|
||||
Gauge
|
||||
Histogram
|
||||
Summary
|
||||
)
|
||||
|
||||
func (m MetricType) Register(metric *metrics) error {
|
||||
switch metric.t {
|
||||
case Counter:
|
||||
return m.counterHandler(metric)
|
||||
case Gauge:
|
||||
return m.gaugeHandler(metric)
|
||||
case Histogram:
|
||||
return m.histogramHandler(metric)
|
||||
case Summary:
|
||||
return m.summaryHandler(metric)
|
||||
}
|
||||
|
||||
return errors.Errorf("metric type is not compatible.")
|
||||
}
|
||||
|
||||
func (m MetricType) counterHandler(metric *metrics) error {
|
||||
metric.v = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{Name: metric.n, Help: metric.d},
|
||||
metric.l,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m MetricType) gaugeHandler(metric *metrics) error {
|
||||
metric.v = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{Name: metric.n, Help: metric.d},
|
||||
metric.l,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m MetricType) histogramHandler(metric *metrics) error {
|
||||
if len(metric.b) == 0 {
|
||||
return errors.Errorf("metric '%s' is histogram type, cannot lose bucket param.", metric.n)
|
||||
}
|
||||
metric.v = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{Name: metric.n, Help: metric.d, Buckets: metric.b},
|
||||
metric.l,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m MetricType) summaryHandler(metric *metrics) error {
|
||||
if len(metric.o) == 0 {
|
||||
return errors.Errorf("metric '%s' is summary type, cannot lose objectives param.", metric.n)
|
||||
}
|
||||
prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{Name: metric.n, Help: metric.d, Objectives: metric.o},
|
||||
metric.l,
|
||||
)
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user