| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | package oldmetrix |
| 4 | |
| 5 | import ( |
| 6 | "errors" |
| 7 | |
| 8 | "github.com/netdata/netdata/go/plugins/pkg/stm" |
| 9 | ) |
| 10 | |
| 11 | type ( |
| 12 | // Counter is a Metric that represents a single numerical bits that only ever |
| 13 | // goes up. That implies that it cannot be used to count items whose number can |
| 14 | // also go down, e.g. the number of currently running goroutines. Those |
| 15 | // "counters" are represented by Gauges. |
| 16 | // |
| 17 | // A Counter is typically used to count requests served, tasks completed, errors |
| 18 | // occurred, etc. |
| 19 | Counter struct { |
| 20 | valInt int64 |
| 21 | valFloat float64 |
| 22 | } |
| 23 | |
| 24 | // CounterVec is a Collector that bundles a set of Counters which have different values for their names. |
| 25 | // This is used if you want to count the same thing partitioned by various dimensions |
| 26 | // (e.g. number of HTTP requests, partitioned by response code and method). |
| 27 | // |
| 28 | // Create instances with NewCounterVec. |
| 29 | CounterVec map[string]*Counter |
| 30 | ) |
| 31 | |
| 32 | var ( |
| 33 | _ stm.Value = Counter{} |
| 34 | _ stm.Value = CounterVec{} |
| 35 | ) |
| 36 | |
| 37 | // WriteTo writes its value into given map. |
| 38 | func (c Counter) WriteTo(rv map[string]int64, key string, mul, div int) { |
| 39 | rv[key] = int64(c.Value() * float64(mul) / float64(div)) |
| 40 | } |
| 41 | |
| 42 | // Value gets current counter. |
| 43 | func (c Counter) Value() float64 { |
| 44 | return float64(c.valInt) + c.valFloat |
| 45 | } |
| 46 | |
| 47 | // Inc increments the counter by 1. Use Add to increment it by arbitrary |
| 48 | // non-negative values. |
| 49 | func (c *Counter) Inc() { |
| 50 | c.valInt++ |
| 51 | } |
| 52 | |
| 53 | // Add adds the given bits to the counter. It panics if the value is < 0. |
| 54 | func (c *Counter) Add(v float64) { |
| 55 | if v < 0 { |
| 56 | panic(errors.New("counter cannot decrease in value")) |
| 57 | } |
| 58 | val := int64(v) |
| 59 | if float64(val) == v { |
| 60 | c.valInt += val |
| 61 | return |
| 62 | } |
| 63 | c.valFloat += v |
| 64 | } |
| 65 | |
| 66 | // NewCounterVec creates a new CounterVec |
| 67 | func NewCounterVec() CounterVec { |
| 68 | return CounterVec{} |
| 69 | } |
| 70 | |
| 71 | // WriteTo writes its value into given map. |
| 72 | func (c CounterVec) WriteTo(rv map[string]int64, key string, mul, div int) { |
| 73 | for name, value := range c { |
| 74 | rv[key+"_"+name] = int64(value.Value() * float64(mul) / float64(div)) |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | // Get gets counter instance by name |
| 79 | func (c CounterVec) Get(name string) *Counter { |
| 80 | item, _ := c.GetP(name) |
| 81 | return item |
| 82 | } |
| 83 | |
| 84 | // GetP gets counter instance by name |
| 85 | func (c CounterVec) GetP(name string) (counter *Counter, ok bool) { |
| 86 | counter, ok = c[name] |
| 87 | if ok { |
| 88 | return |
| 89 | } |
| 90 | counter = &Counter{} |
| 91 | c[name] = counter |
| 92 | return |
| 93 | } |