github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/selfmonitor/metrics_imp.go (about) 1 // Copyright 2021 iLogtail Authors 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 selfmonitor 16 17 import ( 18 "sync" 19 "sync/atomic" 20 "time" 21 22 "github.com/alibaba/ilogtail/pkg/protocol" 23 ) 24 25 var mu sync.Mutex 26 27 type StrMetric struct { 28 name string 29 value string 30 labels []*protocol.Log_Content 31 } 32 33 func (s *StrMetric) Name() string { 34 return getNameWithLables(s.name, s.labels) 35 } 36 37 func (s *StrMetric) Set(v string) { 38 mu.Lock() 39 s.value = v 40 mu.Unlock() 41 } 42 43 func (s *StrMetric) Get() string { 44 mu.Lock() 45 v := s.value 46 mu.Unlock() 47 return v 48 } 49 50 func (s *StrMetric) Collect() string { 51 mu.Lock() 52 v := s.value 53 s.value = "" 54 mu.Unlock() 55 return v 56 } 57 58 type NormalMetric struct { 59 name string 60 value int64 61 labels []*protocol.Log_Content 62 } 63 64 func (s *NormalMetric) Add(v int64) { 65 atomic.AddInt64(&s.value, v) 66 } 67 68 func (s *NormalMetric) Clear(v int64) { 69 atomic.StoreInt64(&s.value, v) 70 } 71 72 func (s *NormalMetric) Get() int64 { 73 return atomic.LoadInt64(&s.value) 74 } 75 76 func (s *NormalMetric) Name() string { 77 return getNameWithLables(s.name, s.labels) 78 } 79 80 func (s *NormalMetric) Collect() int64 { 81 return atomic.SwapInt64(&s.value, 0) 82 } 83 84 type AvgMetric struct { 85 name string 86 value int64 87 count int64 88 prevAvg float64 89 labels []*protocol.Log_Content 90 } 91 92 func (s *AvgMetric) Add(v int64) { 93 mu.Lock() 94 s.value += v 95 s.count++ 96 mu.Unlock() 97 } 98 99 func (s *AvgMetric) Clear(v int64) { 100 mu.Lock() 101 s.value = 0 102 s.count = 0 103 s.prevAvg = 0.0 104 mu.Unlock() 105 } 106 107 func (s *AvgMetric) Get() int64 { 108 return int64(s.GetAvg()) 109 } 110 111 func (s *AvgMetric) GetAvg() float64 { 112 var avg float64 113 mu.Lock() 114 if s.count > 0 { 115 s.prevAvg, avg = float64(s.value)/float64(s.count), float64(s.value)/float64(s.count) 116 s.value = 0 117 s.count = 0 118 } else { 119 avg = s.prevAvg 120 } 121 mu.Unlock() 122 return avg 123 } 124 125 func (s *AvgMetric) Name() string { 126 return getNameWithLables(s.name, s.labels) 127 } 128 129 func (s *AvgMetric) Collect() int64 { 130 var avg float64 131 mu.Lock() 132 if s.count > 0 { 133 s.prevAvg, avg = float64(s.value)/float64(s.count), float64(s.value)/float64(s.count) 134 s.value = 0 135 s.count = 0 136 } else { 137 avg = s.prevAvg 138 } 139 s.value = 0 140 s.count = 0 141 s.prevAvg = 0.0 142 mu.Unlock() 143 return int64(avg) 144 } 145 146 type LatMetric struct { 147 name string 148 t time.Time 149 count int 150 latencySum time.Duration 151 labels []*protocol.Log_Content 152 } 153 154 func (s *LatMetric) Name() string { 155 return getNameWithLables(s.name, s.labels) 156 } 157 158 func (s *LatMetric) Begin() { 159 mu.Lock() 160 s.t = time.Now() 161 mu.Unlock() 162 } 163 164 func (s *LatMetric) End() { 165 endT := time.Now() 166 mu.Lock() 167 s.count++ 168 s.latencySum += endT.Sub(s.t) 169 mu.Unlock() 170 } 171 172 func (s *LatMetric) Clear() { 173 mu.Lock() 174 s.count = 0 175 s.latencySum = 0 176 s.t = time.Unix(0, 0) 177 mu.Unlock() 178 } 179 180 func (s *LatMetric) Get() int64 { 181 mu.Lock() 182 v := int64(0) 183 if s.count != 0 { 184 v = int64(s.latencySum) / int64(s.count) 185 } 186 mu.Unlock() 187 return v 188 } 189 190 func (s *LatMetric) Collect() int64 { 191 mu.Lock() 192 v := int64(0) 193 if s.count != 0 { 194 v = int64(s.latencySum) / int64(s.count) 195 } 196 s.count = 0 197 s.latencySum = 0 198 s.t = time.Unix(0, 0) 199 mu.Unlock() 200 return v 201 } 202 203 func getNameWithLables(name string, labels []*protocol.Log_Content) string { 204 n := name 205 for _, lable := range labels { 206 n = n + "#" + lable.Key + "=" + lable.Value 207 } 208 return n 209 }