pkg/selfmonitor/metrics_imp.go (166 lines of code) (raw):
// Copyright 2021 iLogtail Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package selfmonitor
import (
"sync"
"sync/atomic"
"time"
"github.com/alibaba/ilogtail/pkg/protocol"
)
var mu sync.Mutex
type StrMetric struct {
name string
value string
labels []*protocol.Log_Content
}
func (s *StrMetric) Name() string {
return getNameWithLables(s.name, s.labels)
}
func (s *StrMetric) Set(v string) {
mu.Lock()
s.value = v
mu.Unlock()
}
func (s *StrMetric) Get() string {
mu.Lock()
v := s.value
mu.Unlock()
return v
}
func (s *StrMetric) Collect() string {
mu.Lock()
v := s.value
s.value = ""
mu.Unlock()
return v
}
type NormalMetric struct {
name string
value int64
labels []*protocol.Log_Content
}
func (s *NormalMetric) Add(v int64) {
atomic.AddInt64(&s.value, v)
}
func (s *NormalMetric) Clear(v int64) {
atomic.StoreInt64(&s.value, v)
}
func (s *NormalMetric) Get() int64 {
return atomic.LoadInt64(&s.value)
}
func (s *NormalMetric) Name() string {
return getNameWithLables(s.name, s.labels)
}
func (s *NormalMetric) Collect() int64 {
return atomic.SwapInt64(&s.value, 0)
}
type AvgMetric struct {
name string
value int64
count int64
prevAvg float64
labels []*protocol.Log_Content
}
func (s *AvgMetric) Add(v int64) {
mu.Lock()
s.value += v
s.count++
mu.Unlock()
}
func (s *AvgMetric) Clear(v int64) {
mu.Lock()
s.value = 0
s.count = 0
s.prevAvg = 0.0
mu.Unlock()
}
func (s *AvgMetric) Get() int64 {
return int64(s.GetAvg())
}
func (s *AvgMetric) GetAvg() float64 {
var avg float64
mu.Lock()
if s.count > 0 {
s.prevAvg, avg = float64(s.value)/float64(s.count), float64(s.value)/float64(s.count)
s.value = 0
s.count = 0
} else {
avg = s.prevAvg
}
mu.Unlock()
return avg
}
func (s *AvgMetric) Name() string {
return getNameWithLables(s.name, s.labels)
}
func (s *AvgMetric) Collect() int64 {
var avg float64
mu.Lock()
if s.count > 0 {
s.prevAvg, avg = float64(s.value)/float64(s.count), float64(s.value)/float64(s.count)
s.value = 0
s.count = 0
} else {
avg = s.prevAvg
}
s.value = 0
s.count = 0
s.prevAvg = 0.0
mu.Unlock()
return int64(avg)
}
type LatMetric struct {
name string
t time.Time
count int
latencySum time.Duration
labels []*protocol.Log_Content
}
func (s *LatMetric) Name() string {
return getNameWithLables(s.name, s.labels)
}
func (s *LatMetric) Begin() {
mu.Lock()
s.t = time.Now()
mu.Unlock()
}
func (s *LatMetric) End() {
endT := time.Now()
mu.Lock()
s.count++
s.latencySum += endT.Sub(s.t)
mu.Unlock()
}
func (s *LatMetric) Clear() {
mu.Lock()
s.count = 0
s.latencySum = 0
s.t = time.Unix(0, 0)
mu.Unlock()
}
func (s *LatMetric) Get() int64 {
mu.Lock()
v := int64(0)
if s.count != 0 {
v = int64(s.latencySum) / int64(s.count)
}
mu.Unlock()
return v
}
func (s *LatMetric) Collect() int64 {
mu.Lock()
v := int64(0)
if s.count != 0 {
v = int64(s.latencySum) / int64(s.count)
}
s.count = 0
s.latencySum = 0
s.t = time.Unix(0, 0)
mu.Unlock()
return v
}
func getNameWithLables(name string, labels []*protocol.Log_Content) string {
n := name
for _, lable := range labels {
n = n + "#" + lable.Key + "=" + lable.Value
}
return n
}