go.ligato.io/vpp-agent/v3@v3.5.0/plugins/govppmux/stats.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package govppmux 16 17 import ( 18 "expvar" 19 "os" 20 "sync" 21 "time" 22 23 "go.ligato.io/vpp-agent/v3/pkg/metrics" 24 "go.ligato.io/vpp-agent/v3/proto/ligato/govppmux" 25 "google.golang.org/protobuf/proto" 26 ) 27 28 // DisableOldStats is used to disabled old way of collecting stats. 29 var DisableOldStats = os.Getenv("GOVPPMUX_OLDSTATS_DISABLED") != "" 30 31 var ( 32 stats Stats 33 statsMu sync.RWMutex 34 ) 35 36 func init() { 37 if DisableOldStats { 38 return 39 } 40 stats.Metrics = &govppmux.Metrics{} 41 stats.Errors = make(metrics.Calls) 42 stats.Messages = make(metrics.Calls) 43 stats.Replies = make(metrics.Calls) 44 metrics.Register(&govppmux.Metrics{}, func() interface{} { 45 return &GetStats().Metrics 46 }) 47 expvar.Publish("govppmux.stats", expvar.Func(func() interface{} { 48 return &GetStats().Metrics 49 })) 50 } 51 52 func GetStats() *Stats { 53 if DisableOldStats { 54 return nil 55 } 56 statsMu.RLock() 57 s := &Stats{ 58 Metrics: proto.Clone(stats.Metrics).(*govppmux.Metrics), 59 Errors: stats.Errors.Copy(), 60 AllMessages: stats.AllMessages, 61 Messages: stats.Messages.Copy(), 62 Replies: stats.Replies.Copy(), 63 } 64 statsMu.RUnlock() 65 return s 66 } 67 68 // Stats defines various statistics for govppmux plugin. 69 type Stats struct { 70 *govppmux.Metrics 71 72 Errors metrics.Calls 73 74 AllMessages metrics.CallStats 75 Messages metrics.Calls 76 77 Replies metrics.Calls 78 } 79 80 func (s *Stats) getOrCreateMessage(msg string) *metrics.CallStats { 81 statsMu.RLock() 82 ms, ok := s.Messages[msg] 83 statsMu.RUnlock() 84 if !ok { 85 ms = &metrics.CallStats{Name: msg} 86 statsMu.Lock() 87 s.Messages[msg] = ms 88 statsMu.Unlock() 89 } 90 return ms 91 } 92 93 func trackMsgRequestDur(m string, d time.Duration) { 94 ms := stats.getOrCreateMessage(m) 95 statsMu.Lock() 96 ms.Increment(d) 97 stats.AllMessages.Increment(d) 98 statsMu.Unlock() 99 } 100 101 func (s *Stats) getOrCreateReply(msg string) *metrics.CallStats { 102 statsMu.RLock() 103 ms, ok := s.Replies[msg] 104 statsMu.RUnlock() 105 if !ok { 106 ms = &metrics.CallStats{Name: msg} 107 statsMu.Lock() 108 s.Replies[msg] = ms 109 statsMu.Unlock() 110 } 111 return ms 112 } 113 114 func trackMsgReply(m string) { 115 ms := stats.getOrCreateReply(m) 116 statsMu.Lock() 117 ms.Increment(0) 118 statsMu.Unlock() 119 } 120 121 func (s *Stats) getOrCreateError(msg string) *metrics.CallStats { 122 statsMu.RLock() 123 ms, ok := s.Errors[msg] 124 statsMu.RUnlock() 125 if !ok { 126 ms = &metrics.CallStats{Name: msg} 127 statsMu.Lock() 128 s.Errors[msg] = ms 129 statsMu.Unlock() 130 } 131 return ms 132 } 133 134 func trackError(m string) { 135 ms := stats.getOrCreateError(m) 136 statsMu.Lock() 137 ms.Increment(0) 138 statsMu.Unlock() 139 }