github.com/XiaoMi/Gaea@v1.2.5/stats/counter.go (about)

     1  /*
     2  Copyright 2018 The Vitess Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package stats
    18  
    19  import (
    20  	"strconv"
    21  
    22  	"github.com/XiaoMi/Gaea/log"
    23  	"github.com/XiaoMi/Gaea/util/sync2"
    24  )
    25  
    26  // Counter tracks a cumulative count of a metric.
    27  // For a one-dimensional or multi-dimensional counter, please use
    28  // CountersWithSingleLabel or CountersWithMultiLabels instead.
    29  type Counter struct {
    30  	i    sync2.AtomicInt64
    31  	help string
    32  }
    33  
    34  // NewCounter returns a new Counter.
    35  func NewCounter(name string, help string) *Counter {
    36  	v := &Counter{help: help}
    37  	if name != "" {
    38  		publish(name, v)
    39  	}
    40  	return v
    41  }
    42  
    43  // Add adds the provided value to the Counter.
    44  func (v *Counter) Add(delta int64) {
    45  	if delta < 0 {
    46  		log.Warn("[stats] Adding a negative value to a counter, %v should be a gauge instead", v)
    47  	}
    48  	v.i.Add(delta)
    49  }
    50  
    51  // Reset resets the counter value to 0.
    52  func (v *Counter) Reset() {
    53  	v.i.Set(int64(0))
    54  }
    55  
    56  // Get returns the value.
    57  func (v *Counter) Get() int64 {
    58  	return v.i.Get()
    59  }
    60  
    61  // String implements the expvar.Var interface.
    62  func (v *Counter) String() string {
    63  	return strconv.FormatInt(v.i.Get(), 10)
    64  }
    65  
    66  // Help returns the help string.
    67  func (v *Counter) Help() string {
    68  	return v.help
    69  }
    70  
    71  // CounterFunc allows to provide the counter value via a custom function.
    72  // For implementations that differentiate between Counters/Gauges,
    73  // CounterFunc's values only go up (or are reset to 0).
    74  type CounterFunc struct {
    75  	F    func() int64
    76  	help string
    77  }
    78  
    79  // NewCounterFunc creates a new CounterFunc instance and publishes it if name is
    80  // set.
    81  func NewCounterFunc(name string, help string, f func() int64) *CounterFunc {
    82  	c := &CounterFunc{
    83  		F:    f,
    84  		help: help,
    85  	}
    86  
    87  	if name != "" {
    88  		publish(name, c)
    89  	}
    90  	return c
    91  }
    92  
    93  // Help returns the help string.
    94  func (cf CounterFunc) Help() string {
    95  	return cf.help
    96  }
    97  
    98  // String implements expvar.Var.
    99  func (cf CounterFunc) String() string {
   100  	return strconv.FormatInt(cf.F(), 10)
   101  }
   102  
   103  // Gauge tracks the current value of an integer metric.
   104  // The emphasis here is on *current* i.e. this is not a cumulative counter.
   105  // For a one-dimensional or multi-dimensional gauge, please use
   106  // GaugeWithSingleLabel or GaugesWithMultiLabels instead.
   107  type Gauge struct {
   108  	Counter
   109  }
   110  
   111  // NewGauge creates a new Gauge and publishes it if name is set.
   112  func NewGauge(name string, help string) *Gauge {
   113  	v := &Gauge{Counter: Counter{help: help}}
   114  
   115  	if name != "" {
   116  		publish(name, v)
   117  	}
   118  	return v
   119  }
   120  
   121  // Set overwrites the current value.
   122  func (v *Gauge) Set(value int64) {
   123  	v.Counter.i.Set(value)
   124  }
   125  
   126  // Add adds the provided value to the Gauge.
   127  func (v *Gauge) Add(delta int64) {
   128  	v.Counter.i.Add(delta)
   129  }
   130  
   131  // GaugeFunc is the same as CounterFunc but meant for gauges.
   132  // It's a wrapper around CounterFunc for values that go up/down for
   133  // implementations (like Prometheus) that need to differ between Counters and
   134  // Gauges.
   135  type GaugeFunc struct {
   136  	CounterFunc
   137  }
   138  
   139  // NewGaugeFunc creates a new GaugeFunc instance and publishes it if name is
   140  // set.
   141  func NewGaugeFunc(name string, help string, f func() int64) *GaugeFunc {
   142  	i := &GaugeFunc{
   143  		CounterFunc: CounterFunc{
   144  			F:    f,
   145  			help: help,
   146  		}}
   147  
   148  	if name != "" {
   149  		publish(name, i)
   150  	}
   151  	return i
   152  }