Merge branch 'master' into 13937-keepstore-prometheus
[arvados.git] / services / keepstore / stats_ticker.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package main
6
7 import (
8         "sync"
9         "sync/atomic"
10
11         "github.com/prometheus/client_golang/prometheus"
12 )
13
14 type statsTicker struct {
15         Errors   uint64
16         InBytes  uint64
17         OutBytes uint64
18
19         // Prometheus metrics
20         errors      prometheus.Counter
21         inBytes     prometheus.Counter
22         outBytes    prometheus.Counter
23         errCounters *prometheus.CounterVec
24
25         ErrorCodes map[string]uint64 `json:",omitempty"`
26         lock       sync.Mutex
27 }
28
29 func (s *statsTicker) setup(m *volumeMetrics) {
30         s.errors = m.Errors
31         s.errCounters = m.ErrorCodes
32         s.inBytes = m.InBytes
33         s.outBytes = m.OutBytes
34 }
35
36 // Tick increments each of the given counters by 1 using
37 // atomic.AddUint64.
38 func (s *statsTicker) Tick(counters ...*uint64) {
39         for _, counter := range counters {
40                 atomic.AddUint64(counter, 1)
41         }
42 }
43
44 // TickErr increments the overall error counter, as well as the
45 // ErrorCodes entry for the given errType. If err is nil, TickErr is a
46 // no-op.
47 func (s *statsTicker) TickErr(err error, errType string) {
48         if err == nil {
49                 return
50         }
51         if s.errors != nil {
52                 s.errors.Inc()
53         }
54         s.Tick(&s.Errors)
55
56         s.lock.Lock()
57         if s.ErrorCodes == nil {
58                 s.ErrorCodes = make(map[string]uint64)
59         }
60         s.ErrorCodes[errType]++
61         s.lock.Unlock()
62         if s.errCounters != nil {
63                 s.errCounters.WithLabelValues(errType).Inc()
64         }
65 }
66
67 // TickInBytes increments the incoming byte counter by n.
68 func (s *statsTicker) TickInBytes(n uint64) {
69         if s.inBytes != nil {
70                 s.inBytes.Add(float64(n))
71         }
72         atomic.AddUint64(&s.InBytes, n)
73 }
74
75 // TickOutBytes increments the outgoing byte counter by n.
76 func (s *statsTicker) TickOutBytes(n uint64) {
77         if s.outBytes != nil {
78                 s.outBytes.Add(float64(n))
79         }
80         atomic.AddUint64(&s.OutBytes, n)
81 }